Пример #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);
                }
            }
        }
Пример #2
0
 /// <summary>
 /// Enumerates patches for the given patch codes and ProductCodes and writes them to the pipeline.
 /// </summary>
 /// <param name="patchCode">The patch code to enumerate.</param>
 /// <param name="productCode">The ProductCode having patches to enumerate.</param>
 /// <param name="userSid">The user's SID for patches to enumerate.</param>
 /// <param name="context">The installation context for patches to enumerate.</param>
 /// <param name="filter">The patch installation state for patches to enumerate.</param>
 private void WritePatches(string patchCode, string productCode, string userSid, UserContexts context, PatchStates filter)
 {
     foreach (PatchInstallation patch in PatchInstallation.GetPatches(patchCode, productCode, userSid, context, filter))
     {
         this.WritePatch(patch);
     }
 }