Пример #1
0
        /// <summary>
        /// Enumerates patch installations based on certain criteria.
        /// </summary>
        /// <param name="patchCode">PatchCode (GUID) of the patch to be enumerated. Only
        /// instances of patches 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 patches in the specified
        /// context.</param>
        /// <param name="targetProductCode">ProductCode (GUID) product whose patches are to be
        /// enumerated. If non-null, patch enumeration is restricted to instances of this product
        /// within the specified context. If null, the patches for all products under the specified
        /// context are enumerated.</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="userSid"/> must be null.</param>
        /// <param name="context">Specifies the user context.</param>
        /// <param name="states">The <see cref="PatchStates"/> of patches to return.</param>
        /// <remarks><p>
        /// Win32 MSI APIs:
        /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msienumpatchesex.asp">MsiEnumPatchesEx</a>
        /// </p></remarks>
        public static IEnumerable <PatchInstallation> GetPatches(
            string patchCode,
            string targetProductCode,
            string userSid,
            UserContexts context,
            PatchStates states)
        {
            StringBuilder buf = new StringBuilder(40);
            StringBuilder targetProductBuf = new StringBuilder(40);
            UserContexts  targetContext;
            StringBuilder targetSidBuf = new StringBuilder(40);

            for (uint i = 0; ; i++)
            {
                uint targetSidBufSize = (uint)targetSidBuf.Capacity;
                uint ret = NativeMethods.MsiEnumPatchesEx(
                    targetProductCode,
                    userSid,
                    context,
                    (uint)states,
                    i,
                    buf,
                    targetProductBuf,
                    out targetContext,
                    targetSidBuf,
                    ref targetSidBufSize);
                if (ret == (uint)NativeMethods.Error.MORE_DATA)
                {
                    targetSidBuf.Capacity = (int)++targetSidBufSize;
                    ret = NativeMethods.MsiEnumPatchesEx(
                        targetProductCode,
                        userSid,
                        context,
                        (uint)states,
                        i,
                        buf,
                        targetProductBuf,
                        out targetContext,
                        targetSidBuf,
                        ref targetSidBufSize);
                }

                if (ret == (uint)NativeMethods.Error.NO_MORE_ITEMS)
                {
                    break;
                }

                if (ret != 0)
                {
                    throw InstallerException.ExceptionFromReturnCode(ret);
                }

                string thisPatchCode = buf.ToString();
                if (patchCode == null || patchCode == thisPatchCode)
                {
                    yield return(new PatchInstallation(
                                     buf.ToString(),
                                     targetProductBuf.ToString(),
                                     targetSidBuf.ToString(),
                                     targetContext));
                }
            }
        }