HOWTO: Use the SetupAPI's SetupIterateCabinet() Function

Summary

This article contains a sample that demonstrates how to use the SetupAPI's SetupIterateCabinet() function to extract files out of a CAB file. When you use SetupIterateCabinet(), you do not need an .inf file.

More Information

This sample looks for a CAB file named TestCab.cab. You should put TestCab.cab in the same folder as the sample executable file.


NOTE: Extracting Files from Windows 95 and Windows 98 system cabinet files using the Setup API is not supported. The cabinet files from which the Setup API will extract files should be developer-authored using the CAB SDK (MakeCab.exe). Under Windows 95, the Setup API could extract files from operating system cabinets, but this does not work under Windows 98 and this is by design.

It was never intended (or supported) for developers to extract files from operating systems files using the Setup API. The supported method is to use Extract.exe.


Sample Code

Create a new console application in Visual C++ version 5.0, and add the following code:

   #include <windows.h>    // Includes basic windows functionality.
#include <stdio.h> // Includes the standard i/o functions.
#include <string.h> // Includes the string functions.
#include <tchar.h> // Includes the string functions.
#include <setupapi.h> // Includes the SetupAPI.

// Link with SetupAPI.Lib.
#pragma comment (lib, "setupapi.lib")

#define CAB_FILE_NAME TEXT("TestCab.Cab")

// Global variable holding destination directory.
TCHAR g_szTargetPath[MAX_PATH];

void IterateCabinet(PTSTR pszCabFile);

void main()
{
TCHAR szSourcePath[MAX_PATH];
TCHAR szInfFileName[MAX_PATH];

GetModuleFileName(NULL, szSourcePath, MAX_PATH);
// Strip setup.exe off path.
*(strrchr(szSourcePath, '\\') + 1) = '\0';


// Make the .exe directory the Target directory.
lstrcpy(g_szTargetPath, szSourcePath);

// Assume that CAB_FILE_NAME is in the .exe directory.
lstrcpy(szInfFileName, szSourcePath);
lstrcat(szInfFileName, CAB_FILE_NAME);

IterateCabinet(szInfFileName);
}


LRESULT
WINAPI
CabinetCallback ( IN PVOID pMyInstallData,
IN UINT Notification,
IN UINT Param1,
IN UINT Param2 )
{
LRESULT lRetVal = NO_ERROR;
TCHAR szTarget[MAX_PATH];
FILE_IN_CABINET_INFO *pInfo = NULL;
FILEPATHS *pFilePaths = NULL;

lstrcpy(szTarget,g_szTargetPath);

switch(Notification)
{
case SPFILENOTIFY_FILEINCABINET:
pInfo = (FILE_IN_CABINET_INFO *)Param1;
lstrcat(szTarget, pInfo->NameInCabinet);
lstrcpy(pInfo->FullTargetName, szTarget);
lRetVal = FILEOP_DOIT; // Extract the file.
break;

case SPFILENOTIFY_FILEEXTRACTED:
pFilePaths = (FILEPATHS *)Param1;
printf ( "Extracted %s\n",pFilePaths->Target);
lRetVal = NO_ERROR;
break;

case SPFILENOTIFY_NEEDNEWCABINET: // Unexpected.
lRetVal = NO_ERROR;
break;
}

return lRetVal;
}

void IterateCabinet(PTSTR pszCabFile)
{
LPVOID lpMsgBuf;

if ( !SetupIterateCabinet(pszCabFile,
0, (PSP_FILE_CALLBACK)CabinetCallback, 0) )
{
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
GetLastError(), MAKELANGID(LANG_NEUTRAL,
SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );

MessageBox( NULL,(LPTSTR) lpMsgBuf,
"SetupIterateCabinet() Error :",
MB_OK | MB_ICONEXCLAMATION | MB_TOPMOST);
}
}
Propiedades

Id. de artículo: 189085 - Última revisión: 06/22/2014 - Revisión: 1

Comentarios