/// <summary> /// Retrieve product information for an installed or advertised product. Products installed under a different user account may be queried /// if the calling process has administrative privileges. Advertised products under a per-user-unmanaged context can only be queried by /// the current user. /// </summary> /// <param name="productCode">The ProductCode (GUID) of the product instance being queried.</param> /// <param name="userSid">The security identifier for a specific user or <see langword="null"/> for the currently logged-on user. /// The special SID, "S-1-5-18", cannot be used. To access per-machine installed products, set the <paramref name="userSid"/> /// to <see langword="null"/> and <paramref name="context"/> to <see cref="MsiInstallContext.MACHINE"/>. </param> /// <param name="context">The installation context of the product instance to query.</param> /// <param name="property">The property to query. Only /// <seealso href="https://docs.microsoft.com/en-us/windows/desktop/Msi/required-properties">required properties</seealso> are /// guaranteed to be available.</param> /// <param name="value">If successful, contains the value of the queried property.</param> /// <returns> /// <see cref="Error.SUCCESS"/> if the function completed successfully. /// <see cref="Error.ACCESS_DENIED"/> if the current user has insufficient privileges to get information for a product installed for another user. /// <see cref="Error.BAD_CONFIGURATION"/> if the configuration data for the product is corrupt. /// <see cref="Error.INVALID_PARAMETER"/> if an invalid parameter is passed to the function. /// <see cref="Error.UNKNOWN_PRODUCT"/> if the product is neither advertised nor installed. /// <see cref="Error.UNKNOWN_PROPERTY"/> if the property is unrecognized. /// <see cref="Error.FUNCTION_FAILED"/> if an unexpected, internal failure occurred. /// </returns> public static uint GetProductInfo(string productCode, string?userSid, MsiInstallContext context, string property, out string value) { StringBuilder buffer = new(32); uint bufsize = (uint)buffer.Capacity; uint error = NativeMethods.MsiGetProductInfoEx(productCode, userSid, context, property, buffer, ref bufsize); if (error == Error.MORE_DATA) { // pccValue returns the number of TCHARs required, excluding the null terminating character // so we have to allocate space for it. buffer.Capacity = (int)++bufsize; error = NativeMethods.MsiGetProductInfoEx(productCode, userSid, context, property, buffer, ref bufsize); } value = buffer.ToString(); return(error); }
public static extern uint MsiGetProductInfoEx(string szProductCode, string?szUserSid, MsiInstallContext dwContext, string szProperty, StringBuilder szValue, ref uint pcchValue);