/// <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)); } } }
/// <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); } } }
/// <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); } }