Posted 24 June 2003 - 14:25
to extract your file from the binary table, use this function :
prototype KERNEL32.WriteFile(NUMBER, BINARY, NUMBER, BYREF NUMBER, NUMBER);
// This function is not already prototyped in ISMsiQuery.h
prototype MSI.MsiCloseHandle(HWND);
// private functions to use Dlls
export prototype StreamFileFromBinary(HWND, STRING, STRING);
#define CREATE_ALWAYS 2
////////////////////////////////////////////////////////////////////
//
// Function: StreamFileFromBinary
//
// Purpose: This function will stream out a file from the
// the Binary table.
//
////////////////////////////////////////////////////////////////////
function StreamFileFromBinary(hInstall, szBinaryKey, szFileName)
NUMBER nReturn, nBufSize, nWritten;
STRING szQuery, szRevStream;
HWND hDataBase, hBinaryView, hBinaryRecord, hFile;
begin
//Get the handle to the active database.
hDataBase = MsiGetActiveDatabase(hInstall);
if(hDataBase = 0) then
return ERROR_INSTALL_FAILURE;
endif;
// Get a view of the binary table based on an SQL Query
szQuery = "SELECT * FROM Binary WHERE Name='"
+ szBinaryKey + "'";
// Create the view object for that contains the one
// row that we are interested in
nReturn = MsiDatabaseOpenView(hDataBase, szQuery, hBinaryView);
if(nReturn != ERROR_SUCCESS) then
MsiCloseHandle(hDataBase);
return ERROR_INSTALL_FAILURE;
endif;
// Execute the view before getting the record
nReturn = MsiViewExecute(hBinaryView, NULL);
if(nReturn != ERROR_SUCCESS) then
MsiCloseHandle(hDataBase);
MsiCloseHandle(hBinaryView);
return ERROR_INSTALL_FAILURE;
endif;
// Fetch the first and only record in the view
nReturn = MsiViewFetch(hBinaryView, hBinaryRecord);
if(nReturn != ERROR_SUCCESS) then
MsiCloseHandle(hDataBase);
MsiCloseHandle(hBinaryView);
return ERROR_INSTALL_FAILURE;
endif;
// Create the file in that location using the
// CreateFile Windows API.
hFile = CreateFileA(szFileName, GENERIC_WRITE, 0, 0,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if(hFile = INVALID_HANDLE_VALUE) then
MsiCloseHandle(hDataBase);
MsiCloseHandle(hBinaryView);
MsiCloseHandle(hBinaryRecord);
return ERROR_INSTALL_FAILURE;
endif;
nBufSize = 1023;
// Repeat our extraction of the file until there are
// no more bytes to stream out of the Binary table
repeat
//Read the stream into a buffer, 1023 bytes at a time
nReturn = MsiRecordReadStream(hBinaryRecord, 2, szRevStream,
nBufSize);
// If the operation to stream out the file fails
// then close all handles and return failure. The Windows
// Installer will then terminate the installation.
if(nReturn != ERROR_SUCCESS) then
MsiCloseHandle(hDataBase);
MsiCloseHandle(hBinaryView);
MsiCloseHandle(hBinaryRecord);
CloseHandle(hFile);
return ERROR_INSTALL_FAILURE;
endif;
if(nBufSize > 0)then
//Write the buffer to a file.
nReturn = WriteFile(hFile, szRevStream, nBufSize,
nWritten, 0);
// If the operation to write the file fails
// then close all handles and return failure.
// The Windows Installer will then
// terminate the installation.
if(nReturn == 0) then
MsiCloseHandle(hDataBase);
MsiCloseHandle(hBinaryView);
MsiCloseHandle(hBinaryRecord);
CloseHandle(hFile);
return ERROR_INSTALL_FAILURE;
endif;
endif;
until(nBufSize = 0);
//Close all handles
CloseHandle(hFile);
MsiCloseHandle(hBinaryRecord);
MsiCloseHandle(hDataBase);
MsiCloseHandle(hBinaryView);
return ERROR_SUCCESS;
end;
/////////////////////////////////////
to use this function :
StreamFileFromBinary(hMSI,"DROITS",SUPPORTDIR^"MyAppli.exe");
Your program is extract to the SUPPORTDIR Directory, you can then use it easily with LaunchApp()