// 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. namespace WixToolset.Dtf.WindowsInstaller { using System; using System.Text; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; /// /// Represents an instance of a feature of an installed product. /// public class FeatureInstallation : InstallationPart { /// /// Creates a new FeatureInstallation instance for a feature of a product. /// /// feature name /// ProductCode GUID public FeatureInstallation(string featureName, string productCode) : base(featureName, productCode) { if (String.IsNullOrEmpty(featureName)) { throw new ArgumentNullException("featureName"); } } /// /// Gets the name of the feature. /// public string FeatureName { get { return this.Id; } } /// /// Gets the installed state of the feature. /// ///

/// Win32 MSI API: /// MsiQueryFeatureState ///

public override InstallState State { get { int installState = NativeMethods.MsiQueryFeatureState( this.ProductCode, this.FeatureName); return (InstallState) installState; } } /// /// Gets the parent of the feature, or null if the feature has no parent (it is a root feature). /// /// /// Invocation of this property may be slightly costly for products with many features, /// because it involves an enumeration of all the features in the product. /// public FeatureInstallation Parent { get { StringBuilder featureBuf = new StringBuilder(256); StringBuilder parentBuf = new StringBuilder(256); for (uint i = 0; ; i++) { uint ret = NativeMethods.MsiEnumFeatures(this.ProductCode, i, featureBuf, parentBuf); if (ret != 0) { break; } if (featureBuf.ToString() == this.FeatureName) { if (parentBuf.Length > 0) { return new FeatureInstallation(parentBuf.ToString(), this.ProductCode); } else { return null; } } } return null; } } /// /// Gets the usage metrics for the feature. /// ///

/// If no usage metrics are recorded, the value is 0. ///

/// Win32 MSI API: /// MsiGetFeatureUsage ///

public FeatureInstallation.UsageData Usage { get { uint useCount; ushort useDate; uint ret = NativeMethods.MsiGetFeatureUsage( this.ProductCode, this.FeatureName, out useCount, out useDate); if (ret != 0) { throw InstallerException.ExceptionFromReturnCode(ret); } DateTime lastUsedDate; if (useCount == 0) { lastUsedDate = DateTime.MinValue; } else { lastUsedDate = new DateTime( 1980 + (useDate >> 9), (useDate & 0x01FF) >> 5, (useDate & 0x001F)); } return new UsageData((int) useCount, lastUsedDate); } } /// /// Holds data about the usage of a feature. /// [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")] [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes")] public struct UsageData { private int useCount; private DateTime lastUsedDate; internal UsageData(int useCount, DateTime lastUsedDate) { this.useCount = useCount; this.lastUsedDate = lastUsedDate; } /// /// Gets count of the number of times the feature has been used. /// public int UseCount { get { return this.useCount; } } /// /// Gets the date the feature was last used. /// public DateTime LastUsedDate { get { return this.lastUsedDate; } } } } }