Discussion:
Dynamically insert CAB file into MSI, then run install off MSI file
(too old to reply)
b***@gmail.com
2004-12-22 13:49:17 UTC
Permalink
My application dynamically inserts a CAB file into the MSI file (step
1), then runs product installation off this MSI file (step 2).

Step 1 uses MsiOpenDatabase(...), then MsiDatabaseCommit(...),
MsiCloseHandle(...).

The problem: MsiInstallProduct(...) in step 2 returns error "MSI file
cannot be open" meaning that the file is already open by the process.
For the same reason, I cannot delete this file from the process that
had modified it.

Does anybody know what else should be closed to unlock the MSI file? Or
is it a bug in MSI 2.0?
Phil Wilson
2004-12-22 18:15:18 UTC
Permalink
There's a number of handles you might not have released. What about record
or view handles? Using the PMSIHANDLE class can help resolve this kind of
leak.
--
Phil Wilson [MVP Windows Installer]
----
Post by b***@gmail.com
My application dynamically inserts a CAB file into the MSI file (step
1), then runs product installation off this MSI file (step 2).
Step 1 uses MsiOpenDatabase(...), then MsiDatabaseCommit(...),
MsiCloseHandle(...).
The problem: MsiInstallProduct(...) in step 2 returns error "MSI file
cannot be open" meaning that the file is already open by the process.
For the same reason, I cannot delete this file from the process that
had modified it.
Does anybody know what else should be closed to unlock the MSI file? Or
is it a bug in MSI 2.0?
Mikhail Viner-Bykovskiy
2004-12-23 20:53:00 UTC
Permalink
Actually, I use only PMSIHANDLE variables.
But I found the workarond.

Instead of inserting a CAB file into the MSI file
(which worked fine except for this locking issue) using this code:
_stprintf( buf, _T("insert into `_Streams` (`Name`) values('%s')"),
CABName );
MsiDatabaseOpenView( hPNew, buf, &hView );
MsiViewExecute( hView, 0 );
MsiViewClose( hView )
_stprintf( buf, _T("select * from `_Streams` where `Name`='%s'"),
CABName );
MsiDatabaseOpenView( hPNew, buf, &hView );
MsiViewExecute( hView, 0 );
MsiViewFetch( hView, &hRec );
MsiRecordSetStream( hRec, 2, CABPath );
MsiViewModify( hView, MSIMODIFY_UPDATE, hRec );

I use now this code:
_stprintf( buf, _T("select * from `_Streams`") );
MsiDatabaseOpenView( hPNew, buf, &hView );
hRec = MsiCreateRecord(2);
MsiRecordSetString( hRec, 1, CABName );
MsiRecordSetStream( hRec, 2, CABPath );
MsiViewModify( hView, MSIMODIFY_INSERT, hRec );
Not only better but also shorter :)
Mikhail Viner-Bykovskiy
2004-12-23 20:56:01 UTC
Permalink
Actually, I use only PMSIHANDLE variables.
But I found the workarond.

Instead of inserting a CAB file into the MSI file
(which worked fine except for this locking issue) using this code:
_stprintf( buf, _T("insert into `_Streams` (`Name`) values('%s')"),
CABName );
MsiDatabaseOpenView( hPNew, buf, &hView );
MsiViewExecute( hView, 0 );
MsiViewClose( hView )
_stprintf( buf, _T("select * from `_Streams` where `Name`='%s'"),
CABName );
MsiDatabaseOpenView( hPNew, buf, &hView );
MsiViewExecute( hView, 0 );
MsiViewFetch( hView, &hRec );
MsiRecordSetStream( hRec, 2, CABPath );
MsiViewModify( hView, MSIMODIFY_UPDATE, hRec );

I use now this code:
_stprintf( buf, _T("select * from `_Streams`") );
MsiDatabaseOpenView( hPNew, buf, &hView );
hRec = MsiCreateRecord(2);
MsiRecordSetString( hRec, 1, CABName );
MsiRecordSetStream( hRec, 2, CABPath );
MsiViewModify( hView, MSIMODIFY_INSERT, hRec );
Not only better but also shorter :)

Loading...