/// <summary> /// Enumerates product installations based on certain criteria. /// </summary> /// <param name="productCode">ProductCode (GUID) of the product instances to be enumerated. Only /// instances of products within the scope of the context specified by the /// <paramref name="userSid"/> and <paramref name="context"/> parameters will be /// enumerated. This parameter may be set to null to enumerate all products in the specified /// context.</param> /// <param name="userSid">Specifies a security identifier (SID) that restricts the context /// of enumeration. A SID value other than s-1-1-0 is considered a user SID and restricts /// enumeration to the current user or any user in the system. The special SID string /// s-1-1-0 (Everyone) specifies enumeration across all users in the system. This parameter /// can be set to null to restrict the enumeration scope to the current user. When /// <paramref name="context"/> is set to the machine context only, /// <paramref name="userSid"/> must be null.</param> /// <param name="context">Specifies the user context.</param> /// <returns>An enumeration of product objects for enumerated product instances.</returns> /// <remarks><p> /// Win32 MSI API: /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msienumproductsex.asp">MsiEnumProductsEx</a> /// </p></remarks> public static IEnumerable <ProductInstallation> GetProducts( string productCode, string userSid, UserContexts context) { StringBuilder buf = new StringBuilder(40); UserContexts targetContext; StringBuilder targetSidBuf = new StringBuilder(40); for (uint i = 0; ; i++) { uint targetSidBufSize = (uint)targetSidBuf.Capacity; uint ret = NativeMethods.MsiEnumProductsEx( productCode, userSid, context, i, buf, out targetContext, targetSidBuf, ref targetSidBufSize); if (ret == (uint)NativeMethods.Error.MORE_DATA) { targetSidBuf.Capacity = (int)++targetSidBufSize; ret = NativeMethods.MsiEnumProductsEx( productCode, userSid, context, i, buf, out targetContext, targetSidBuf, ref targetSidBufSize); } if (ret == (uint)NativeMethods.Error.NO_MORE_ITEMS) { break; } if (ret != 0) { throw InstallerException.ExceptionFromReturnCode(ret); } yield return(new ProductInstallation( buf.ToString(), targetSidBuf.ToString(), targetContext)); } }