ARPHelper.h (4923B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #pragma once 4 #include "Microsoft/SQLiteIndex.h" 5 #include <AppInstallerArchitecture.h> 6 #include <winget/Registry.h> 7 #include <winget/ManifestInstaller.h> 8 #include <wil/registry.h> 9 #include <wil/resource.h> 10 11 #include <string> 12 #include <vector> 13 14 namespace AppInstaller::Repository::Microsoft 15 { 16 // A helper to find the various locations that contain ARP (Add/Remove Programs) entries. 17 struct ARPHelper 18 { 19 // See https://docs.microsoft.com/en-us/windows/win32/msi/uninstall-registry-key for details. 20 const std::wstring SubKeyPath{ L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" }; 21 22 // REG_SZ 23 const std::wstring DisplayName{ L"DisplayName" }; 24 // REG_SZ 25 const std::wstring Publisher{ L"Publisher" }; 26 // REG_SZ 27 const std::wstring DisplayVersion{ L"DisplayVersion" }; 28 // REG_DWORD (ex. 0xMMmmbbbb, M[ajor], m[inor], b[uild]) 29 const std::wstring Version{ L"Version" }; 30 // REG_DWORD 31 const std::wstring VersionMajor{ L"VersionMajor" }; 32 // REG_DWORD 33 const std::wstring VersionMinor{ L"VersionMinor" }; 34 // REG_DWORD 35 const std::wstring MajorVersion{ L"MajorVersion" }; 36 // REG_DWORD 37 const std::wstring MinorVersion{ L"MinorVersion" }; 38 // REG_SZ 39 const std::wstring URLInfoAbout{ L"URLInfoAbout" }; 40 // REG_SZ 41 const std::wstring HelpLink{ L"HelpLink" }; 42 // REG_SZ 43 const std::wstring InstallLocation{ L"InstallLocation" }; 44 // REG_DWORD (ex. 1033 [en-us]) 45 const std::wstring Language{ L"Language" }; 46 // REG_SZ (ex. "english") 47 const std::wstring InnoSetupLanguage{ L"Inno Setup: Language" }; 48 // REG_EXPAND_SZ 49 const std::wstring UninstallString{ L"UninstallString" }; 50 // REG_EXPAND_SZ 51 const std::wstring QuietUninstallString{ L"QuietUninstallString" }; 52 // REG_DWORD (bool, true indicates MSI) 53 const std::wstring WindowsInstaller{ L"WindowsInstaller" }; 54 // REG_DWORD (bool) 55 const std::wstring SystemComponent{ L"SystemComponent" }; 56 // REG_SZ 57 const std::wstring DisplayIcon{ L"DisplayIcon" }; 58 // REG_DWORD 59 const std::wstring NoModify{ L"NoModify" }; 60 // REG_DWORD 61 const std::wstring NoRepair{ L"NoRepair" }; 62 // REG_SZ 63 const std::wstring ModifyPath{ L"ModifyPath" }; 64 65 // Gets the registry key associated with the given scope and architecture on this platform. 66 // May return an empty key if there is no valid location (bad combination or not found). 67 Registry::Key GetARPKey(Manifest::ScopeEnum scope, Utility::Architecture architecture) const; 68 69 // Gets the arp registry key associated with the given scope and product code. 70 // May return an empty key if not found. 71 Registry::Key FindARPEntry(const std::string& productCode, AppInstaller::Manifest::ScopeEnum scope = AppInstaller::Manifest::ScopeEnum::Unknown) const; 72 73 // Returns true IFF the value exists and contains a non-zero DWORD. 74 static bool GetBoolValue(const Registry::Key& arpKey, const std::wstring& name); 75 76 // Returns the string value if it exists. 77 static std::string GetStringValue(const Registry::Key& arpKey, const std::wstring& name); 78 79 // Determines the version from an ARP entry. 80 // The priority is: 81 // DisplayVersion 82 // Version 83 // MajorVersion, MinorVersion 84 std::string DetermineVersion(const Registry::Key& arpKey) const; 85 86 // Reads a value and adds it to the metadata if it exists. 87 void AddMetadataIfPresent(const Registry::Key& key, const std::wstring& name, SQLiteIndex& index, SQLiteIndex::IdType manifestId, PackageVersionMetadata metadata) const; 88 89 // Populates the index with the ARP entries from the given scope (machine/user). 90 // Handles all of the architectures for the given scope. 91 void PopulateIndexFromARP(SQLiteIndex& index, Manifest::ScopeEnum scope) const; 92 93 // Populates the index with the ARP entries from the given key. 94 // This entry point is primarily to allow unit tests to operate of arbitrary keys; 95 // product code should use PopulateIndexFromARP. 96 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; 97 98 // Creates registry watchers for the given scope 99 std::vector<wil::unique_registry_watcher> CreateRegistryWatchers(Manifest::ScopeEnum scope, std::function<void(Manifest::ScopeEnum, Utility::Architecture, wil::RegistryChangeKind)> callback); 100 }; 101 }