aboutsummaryrefslogtreecommitdiff
path: root/src/dtf/WixToolset.Dtf.WindowsInstaller/FeatureInstallation.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/dtf/WixToolset.Dtf.WindowsInstaller/FeatureInstallation.cs174
1 files changed, 174 insertions, 0 deletions
diff --git a/src/dtf/WixToolset.Dtf.WindowsInstaller/FeatureInstallation.cs b/src/dtf/WixToolset.Dtf.WindowsInstaller/FeatureInstallation.cs
new file mode 100644
index 00000000..aa8ffe34
--- /dev/null
+++ b/src/dtf/WixToolset.Dtf.WindowsInstaller/FeatureInstallation.cs
@@ -0,0 +1,174 @@
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
3namespace WixToolset.Dtf.WindowsInstaller
4{
5 using System;
6 using System.Text;
7 using System.Collections.Generic;
8 using System.Diagnostics.CodeAnalysis;
9
10 /// <summary>
11 /// Represents an instance of a feature of an installed product.
12 /// </summary>
13 public class FeatureInstallation : InstallationPart
14 {
15 /// <summary>
16 /// Creates a new FeatureInstallation instance for a feature of a product.
17 /// </summary>
18 /// <param name="featureName">feature name</param>
19 /// <param name="productCode">ProductCode GUID</param>
20 public FeatureInstallation(string featureName, string productCode)
21 : base(featureName, productCode)
22 {
23 if (String.IsNullOrEmpty(featureName))
24 {
25 throw new ArgumentNullException("featureName");
26 }
27 }
28
29 /// <summary>
30 /// Gets the name of the feature.
31 /// </summary>
32 public string FeatureName
33 {
34 get
35 {
36 return this.Id;
37 }
38 }
39
40 /// <summary>
41 /// Gets the installed state of the feature.
42 /// </summary>
43 /// <remarks><p>
44 /// Win32 MSI API:
45 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msiqueryfeaturestate.asp">MsiQueryFeatureState</a>
46 /// </p></remarks>
47 public override InstallState State
48 {
49 get
50 {
51 int installState = NativeMethods.MsiQueryFeatureState(
52 this.ProductCode, this.FeatureName);
53 return (InstallState) installState;
54 }
55 }
56
57 /// <summary>
58 /// Gets the parent of the feature, or null if the feature has no parent (it is a root feature).
59 /// </summary>
60 /// <remarks>
61 /// Invocation of this property may be slightly costly for products with many features,
62 /// because it involves an enumeration of all the features in the product.
63 /// </remarks>
64 public FeatureInstallation Parent
65 {
66 get
67 {
68 StringBuilder featureBuf = new StringBuilder(256);
69 StringBuilder parentBuf = new StringBuilder(256);
70 for (uint i = 0; ; i++)
71 {
72 uint ret = NativeMethods.MsiEnumFeatures(this.ProductCode, i, featureBuf, parentBuf);
73
74 if (ret != 0)
75 {
76 break;
77 }
78
79 if (featureBuf.ToString() == this.FeatureName)
80 {
81 if (parentBuf.Length > 0)
82 {
83 return new FeatureInstallation(parentBuf.ToString(), this.ProductCode);
84 }
85 else
86 {
87 return null;
88 }
89 }
90 }
91
92 return null;
93 }
94 }
95
96 /// <summary>
97 /// Gets the usage metrics for the feature.
98 /// </summary>
99 /// <remarks><p>
100 /// If no usage metrics are recorded, the <see cref="UsageData.UseCount" /> value is 0.
101 /// </p><p>
102 /// Win32 MSI API:
103 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msigetfeatureusage.asp">MsiGetFeatureUsage</a>
104 /// </p></remarks>
105 public FeatureInstallation.UsageData Usage
106 {
107 get
108 {
109 uint useCount;
110 ushort useDate;
111 uint ret = NativeMethods.MsiGetFeatureUsage(
112 this.ProductCode, this.FeatureName, out useCount, out useDate);
113 if (ret != 0)
114 {
115 throw InstallerException.ExceptionFromReturnCode(ret);
116 }
117
118 DateTime lastUsedDate;
119 if (useCount == 0)
120 {
121 lastUsedDate = DateTime.MinValue;
122 }
123 else
124 {
125 lastUsedDate = new DateTime(
126 1980 + (useDate >> 9),
127 (useDate & 0x01FF) >> 5,
128 (useDate & 0x001F));
129 }
130
131 return new UsageData((int) useCount, lastUsedDate);
132 }
133 }
134
135 /// <summary>
136 /// Holds data about the usage of a feature.
137 /// </summary>
138 [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
139 [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes")]
140 public struct UsageData
141 {
142 private int useCount;
143 private DateTime lastUsedDate;
144
145 internal UsageData(int useCount, DateTime lastUsedDate)
146 {
147 this.useCount = useCount;
148 this.lastUsedDate = lastUsedDate;
149 }
150
151 /// <summary>
152 /// Gets count of the number of times the feature has been used.
153 /// </summary>
154 public int UseCount
155 {
156 get
157 {
158 return this.useCount;
159 }
160 }
161
162 /// <summary>
163 /// Gets the date the feature was last used.
164 /// </summary>
165 public DateTime LastUsedDate
166 {
167 get
168 {
169 return this.lastUsedDate;
170 }
171 }
172 }
173 }
174}