main
cs 114 lines 5.48 KB
Raw
1 // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3 namespace WixToolset.Core.WindowsInstaller.Bind
4 {
5 using System;
6 using System.Collections.Generic;
7 using System.Linq;
8 using WixToolset.Data;
9 using WixToolset.Data.Symbols;
10 using WixToolset.Extensibility.Services;
11
12 internal class ProcessDependencyReferencesCommand
13 {
14 // The root registry key for the dependency extension. We write to Software\Classes explicitly
15 // based on the current security context instead of HKCR. See
16 // https://learn.microsoft.com/en-us/windows/win32/sysinfo/hkey-classes-root-key for more information.
17 private const string DependencyRegistryRoot = @"Software\Classes\Installer\Dependencies\";
18 private const string RegistryDependents = "Dependents";
19
20 public ProcessDependencyReferencesCommand(IBackendHelper backendHelper, IntermediateSection section, IEnumerable<WixDependencyRefSymbol> dependencyRefSymbols)
21 {
22 this.BackendHelper = backendHelper;
23 this.Section = section;
24 this.DependencyRefSymbols = dependencyRefSymbols;
25 }
26
27 private IBackendHelper BackendHelper { get; }
28
29 private IntermediateSection Section { get; }
30
31 private IEnumerable<WixDependencyRefSymbol> DependencyRefSymbols { get; }
32
33 public void Execute()
34 {
35 var wixDependencyRows = this.Section.Symbols.OfType<WixDependencySymbol>().ToDictionary(d => d.Id.Id);
36 var wixDependencyProviderRows = this.Section.Symbols.OfType<WixDependencyProviderSymbol>().ToDictionary(d => d.Id.Id);
37
38 // For each relationship, get the provides and requires rows to generate registry values.
39 foreach (var wixDependencyRefRow in this.DependencyRefSymbols)
40 {
41 var providesId = wixDependencyRefRow.WixDependencyProviderRef;
42 var requiresId = wixDependencyRefRow.WixDependencyRef;
43
44 // If we do not find both symbols, skip the registry key generation.
45 if (!wixDependencyRows.TryGetValue(requiresId, out var wixDependencyRow))
46 {
47 continue;
48 }
49
50 if (!wixDependencyProviderRows.TryGetValue(providesId, out var wixDependencyProviderRow))
51 {
52 continue;
53 }
54
55 // Format the root registry key using the required provider key and the current provider key.
56 var requiresKey = wixDependencyRow.Id.Id;
57 var providesKey = wixDependencyRow.ProviderKey;
58 var keyRequires = String.Format(@"{0}{1}\{2}\{3}", DependencyRegistryRoot, requiresKey, RegistryDependents, providesKey);
59
60 // Get the component ID from the provider.
61 var componentId = wixDependencyProviderRow.ParentRef;
62
63 var id = this.BackendHelper.GenerateIdentifier("reg", providesId, requiresId, "(Default)");
64 this.Section.AddSymbol(new RegistrySymbol(wixDependencyRefRow.SourceLineNumbers, new Identifier(AccessModifier.Section, id))
65 {
66 ComponentRef = componentId,
67 Root = RegistryRootType.MachineUser,
68 Key = keyRequires,
69 Name = "*",
70 });
71
72 if (!String.IsNullOrEmpty(wixDependencyRow.MinVersion))
73 {
74 id = this.BackendHelper.GenerateIdentifier("reg", providesId, requiresId, "MinVersion");
75 this.Section.AddSymbol(new RegistrySymbol(wixDependencyRefRow.SourceLineNumbers, new Identifier(AccessModifier.Section, id))
76 {
77 ComponentRef = componentId,
78 Root = RegistryRootType.MachineUser,
79 Key = keyRequires,
80 Name = "MinVersion",
81 Value = wixDependencyRow.MinVersion
82 });
83 }
84
85 var maxVersion = (string)wixDependencyRow[3];
86 if (!String.IsNullOrEmpty(wixDependencyRow.MaxVersion))
87 {
88 id = this.BackendHelper.GenerateIdentifier("reg", providesId, requiresId, "MaxVersion");
89 this.Section.AddSymbol(new RegistrySymbol(wixDependencyRefRow.SourceLineNumbers, new Identifier(AccessModifier.Section, id))
90 {
91 ComponentRef = componentId,
92 Root = RegistryRootType.MachineUser,
93 Key = keyRequires,
94 Name = "MaxVersion",
95 Value = wixDependencyRow.MaxVersion
96 });
97 }
98
99 if (wixDependencyRow.Attributes != WixDependencySymbolAttributes.None)
100 {
101 id = this.BackendHelper.GenerateIdentifier("reg", providesId, requiresId, "Attributes");
102 this.Section.AddSymbol(new RegistrySymbol(wixDependencyRefRow.SourceLineNumbers, new Identifier(AccessModifier.Section, id))
103 {
104 ComponentRef = componentId,
105 Root = RegistryRootType.MachineUser,
106 Key = keyRequires,
107 Name = "Attributes",
108 Value = String.Concat("#", (int)wixDependencyRow.Attributes)
109 });
110 }
111 }
112 }
113 }
114 }