/// <summary> /// [MSI 4.0] Gets the list of files that can be updated by one or more patches. /// </summary> /// <param name="productCode">ProductCode (GUID) of the product which is /// the target of the patches</param> /// <param name="patches">list of file paths of one or more patches to be /// analyzed</param> /// <returns>List of absolute paths of files that can be updated when the /// patches are applied on this system.</returns> /// <remarks><p> /// Win32 MSI API: /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msigetpatchfilelist.asp">MsiGetPatchFileList</a> /// </p></remarks> public static IList <string> GetPatchFileList(string productCode, IList <string> patches) { if (String.IsNullOrEmpty(productCode)) { throw new ArgumentNullException("productCode"); } if (patches == null || patches.Count == 0) { throw new ArgumentNullException("patches"); } StringBuilder patchList = new StringBuilder(); foreach (string patch in patches) { if (patch != null) { if (patchList.Length != 0) { patchList.Append(';'); } patchList.Append(patch); } } if (patchList.Length == 0) { throw new ArgumentNullException("patches"); } IntPtr phFileRecords; uint cFiles; uint ret = NativeMethods.MsiGetPatchFileList( productCode, patchList.ToString(), out cFiles, out phFileRecords); if (ret != 0) { throw InstallerException.ExceptionFromReturnCode(ret); } List <string> files = new List <string>(); for (uint i = 0; i < cFiles; i++) { int hFileRec = Marshal.ReadInt32(phFileRecords, (int)i); using (Record fileRec = new Record(hFileRec, true, null)) { files.Add(fileRec.GetString(1)); } } return(files); }