Enumeración de los archivos que se pueden actualizar
La función MsiGetPatchFileList y la propiedad PatchFiles del objeto Installer toman una lista de revisiones de Windows Installer (archivos .msp) y devuelven una lista de archivos que esas revisiones pueden actualizar. La función MsiGetPatchFileList y la propiedad PatchFiles están disponibles a partir de Windows Installer 4.0.
Enumeración de los archivos que se pueden actualizar
En el siguiente ejemplo se muestra cómo extraer la información de aplicabilidad de una lista de revisiones de Windows Installer (archivos .msp) mediante MsiGetPatchFileList. La función MsiGetPatchFileList recibe el código de producto del destino de las revisiones y una lista de archivos .msp delimitados por punto y coma. En este ejemplo se requiere que Windows Installer 4.0 se ejecute en Windows Vista.
#include <windows.h>
#include <stdio.h>
#include <Shellapi.h>
#include <msi.h>
#include <Msiquery.h>
#pragma comment(lib, "msi.lib")
#pragma comment(lib, "shell32.lib")
void CloseMsiHandles(MSIHANDLE* phFileListRec, DWORD dwcFiles);
int __cdecl main()
{
UINT uiRet = ERROR_SUCCESS;
int argc;
WCHAR** argv = CommandLineToArgvW(GetCommandLine(), &argc);
MSIHANDLE *phFileListRec = NULL;
DWORD dwcFiles = 0;
WCHAR* szProductCode = argv[1];
WCHAR* szPatchFileList = argv[2];
if(ERROR_SUCCESS != (uiRet = MsiGetPatchFileList(szProductCode, szPatchFileList, &dwcFiles, &phFileListRec)))
{
printf("MsiGetPatchFileListW(%S, ...) Failed with:%d", szProductCode, uiRet);
return uiRet;
}
DWORD cchBuf = 1;
DWORD cchBufSize = 1;
WCHAR* szBuf = new WCHAR[cchBufSize];
if (!szBuf)
{
printf("Failed to allocate memory");
CloseMsiHandles(phFileListRec, dwcFiles);
return ERROR_OUTOFMEMORY;
}
memset(szBuf, 0, sizeof(WCHAR)*cchBufSize);
for(unsigned int i = 0; i < dwcFiles; i++)
{
cchBuf = cchBufSize;
while(ERROR_MORE_DATA == (uiRet = MsiRecordGetString(phFileListRec[i], 0, szBuf, &cchBuf)))
{
if (szBuf)
delete[] szBuf;
cchBufSize = ++cchBuf;
szBuf = new WCHAR[cchBufSize];
if (!szBuf)
{
printf("Failed to allocate memory");
CloseMsiHandles(phFileListRec, dwcFiles);
return ERROR_OUTOFMEMORY;
}
}
if(uiRet != ERROR_SUCCESS)
{
printf("MsiRecordGetString(phFileListRec[%d] with %d", i, uiRet);
CloseMsiHandles(phFileListRec, dwcFiles);
if (szBuf)
delete[] szBuf;
return uiRet;
}
else
{
printf("File %d:%S\n", i, szBuf);
}
}
CloseMsiHandles(phFileListRec, dwcFiles);
if (szBuf)
delete[] szBuf;
return 0;
}
void CloseMsiHandles(MSIHANDLE* phFileListRec, DWORD dwcFiles)
{
if (!phFileListRec)
return;
for (unsigned int i = 0; i < dwcFiles; i++)
{
if (phFileListRec[i])
MsiCloseHandle(phFileListRec[i]);
}
}
//
En el siguiente ejemplo se muestra cómo extraer la información de aplicabilidad de una lista de revisiones de Windows Installer (archivos .msp) mediante la propiedad PatchFiles del objeto Installer. La propiedad PatchFiles recibe el código de producto del destino de las revisiones y una lista de archivos .msp delimitados por punto y coma. En este ejemplo se requiere que Windows Installer 4.0 se ejecute en Windows Vista.
Dim FileList
Dim installer : Set installer = Nothing
Dim argCount:argCount = Wscript.Arguments.Count
Set installer = Wscript.CreateObject("WindowsInstaller.Installer")
If (argCount > 0) Then
sProdCode = Wscript.Arguments(0)
sPatchPckgPath = Wscript.Arguments(1)
Set FileList = installer.PatchFiles (sProdCode, sPatchPckgPath)
For each File in FileList
Wscript.Echo "Affected file: " & File
Next
Else
Usage
End If
Sub Usage
Wscript.Echo "Windows Installer utility to list files updated by a patch for an installed product" &_
vbNewLine & " 1st argument is the product code (GUID) of an installed product" &_
vbNewLine & " 2nd argument is the list of patches" &_
vbNewLine &_
vbNewLine & "Copyright (C) Microsoft. All rights reserved."
Wscript.Quit 1
End Sub