Now, using MsiOpenProduct I want to obtain the value of [CUSTOM], but
I am unable to get the value. For example:
UINT uRet = ::MsiOpenProduct(InstanceTransformProductCode, &hMsi);
CString sCustom;
bufLen = 2048;
uRet = MsiGetProperty(hMsi, _T("CUSTOM"),
sCustom.GetBuffer(bufLen), &bufLen);
sCustom.ReleaseBuffer();
sCustom is empty. I then looked into the msi log created immediately
after MsiOpenProduct is called, I see:
MSI (c) (4C:B0) [17:58:51:097]: PROPERTY CHANGE: Adding PackageCode
property. Its value is '{EF9201EA-EA4D-4127-ADA0-70E3C24F5402}'.
MSI (c) (4C:B0) [17:58:51:097]: Product Code passed to
Engine.Initialize: '(none)'
MSI (c) (4C:B0) [17:58:51:097]: Product Code from property table
before transforms: '{B655E81D-AB84-48FF-8654-202971D90876}'
MSI (c) (4C:B0) [17:58:51:097]: Product Code from property table after
transforms: '{B655E81D-AB84-48FF-8654-202971D90876}'
MSI (c) (4C:B0) [17:58:51:097]: Product not registered: beginning
first-time install
MSI (c) (4C:B0) [17:58:51:097]: PROPERTY CHANGE: Adding ProductState
property. Its value is '-1'.
MSI (c) (4C:B0) [17:58:51:097]: Entering
CMsiConfigurationManager::SetLastUsedSource.
Why isn't api resolving the instance transforms? The log indicates it
is initiating a first time install because the product wasn't
registered? I tried unstalling the product - that worked without
problems. It is the API I am having problems with.
Can someone please shed light on what is happening and if there is a
way to get the Custom property?
PMSIHANDLE hMsi, hMsiActiveDb;
CString strProductCode(_T("{B655E81D-
AB84-48FF-8654-202971D90876}"));
CString strTransforms, sProp;
bufLen = 2048;
MsiGetProductInfo(strProductCode, INSTALLPROPERTY_TRANSFORMS,
strTransforms.GetBuffer(2048), &bufLen);
strTransforms.ReleaseBuffer();
UINT uRet = ::MsiOpenProduct(strProductCode, &hMsi);
hMsiActiveDb = ::MsiGetActiveDatabase(hMsi);
int nErrorConditions = MSITRANSFORM_ERROR_ADDEXISTINGROW
| MSITRANSFORM_ERROR_DELMISSINGROW
| MSITRANSFORM_ERROR_ADDEXISTINGTABLE
| MSITRANSFORM_ERROR_DELMISSINGTABLE
| MSITRANSFORM_ERROR_UPDATEMISSINGROW
| MSITRANSFORM_ERROR_CHANGECODEPAGE;
bufLen = 2048;
uRet = MsiDatabaseApplyTransform(hMsiActiveDb, strTransforms,
nErrorConditions);
uRet = MsiGetProductProperty(hMsi, MSIPROPERTY_MYCUSTOMPROP,
sProp.GetBuffer(2048), &bufLen);
sProp.ReleaseBuffer();
On Apr 25, 2:00 pm, "kis...@gmail.com" <kis...@gmail.com> wrote:
> Sorry, I read the documentation again. It saysMsiOpenProduct"opens a
> > msiexec /I mypackage.msi TRANSFORMS=instance.mstMSINEWINSTANCE=1. The
> > instance transforms contains a custom property (lets say [CUSTOM] =
> > XXX)
>
> > Now, usingMsiOpenProductI want to obtain the value of [CUSTOM], but
> > I am unable to get the value. For example:
>
> > UINT uRet = ::MsiOpenProduct(InstanceTransformProductCode, &hMsi);
>
> > CString sCustom;
> > bufLen = 2048;
> > uRet = MsiGetProperty(hMsi, _T("CUSTOM"),
> > sCustom.GetBuffer(bufLen), &bufLen);
> > sCustom.ReleaseBuffer();
>
> > sCustom is empty. I then looked into the msi log created immediately
> > afterMsiOpenProductis called, I see:
>
> > MSI (c) (4C:B0) [17:58:51:097]: PROPERTY CHANGE: Adding PackageCode
> > property. Its value is '{EF9201EA-EA4D-4127-ADA0-70E3C24F5402}'.
> > MSI (c) (4C:B0) [17:58:51:097]: Product Code passed to
> > Engine.Initialize: '(none)'
> > MSI (c) (4C:B0) [17:58:51:097]: Product Code from property table
> > before transforms: '{B655E81D-AB84-48FF-8654-202971D90876}'
> > MSI (c) (4C:B0) [17:58:51:097]: Product Code from property table after
> > transforms: '{B655E81D-AB84-48FF-8654-202971D90876}'
> > MSI (c) (4C:B0) [17:58:51:097]: Product not registered: beginning
> > first-time install
> > MSI (c) (4C:B0) [17:58:51:097]: PROPERTY CHANGE: Adding ProductState
> > property. Its value is '-1'.
> > MSI (c) (4C:B0) [17:58:51:097]: Entering
> > CMsiConfigurationManager::SetLastUsedSource.
>
> > Why isn't api resolving the instance transforms? The log indicates it
> > is initiating a first time install because the product wasn't
> > registered? I tried unstalling the product - that worked without
> > problems. It is the API I am having problems with.
>
> > Can someone please shed light on what is happening and if there is a
> > way to get the Custom property?- Hide quoted text -
>
> - Show quoted text -
> > - Show quoted text -- Hide quoted text -
I been searching around for a solution to a very similar problem and this
thread is the closest I have come to finding one. I know this is an old
issue to you, but do you think you could help point me in the right
direction?
I am not sure I completely understand your final comment: "I ended up
copying the cached msi to temp folder, changing its product
code to that of the instance transform, and then calling
MsiOpenDatabase and MsiOpenPackage. That works."
MsiOpenPackage will open the cached database with the transform already
applied, right? I have that working, and I see why you do an
MsiOpenDatabase on the copy (so you have to handles to diff to generate a
new transform), but where do you change the value? When I try to apply a
change to the database opened in MsiOpenPackage I get a failure on the view.
The database opened with MsiOpenDatabase, of course, doesn't show me any of
the changes in the transform (even after calling MsiDatabaseApplyTransform.
So I am stuck. I would greatly appreciated it if you could help me out (and
if you are even monitoring this tread any more).
Thanks,
Dave
To work with the Database's data you need to have a MSIHANDLE to the
Database itself. MsiOpenPackage/Ex and MsiOpenProduct give you an
Installation MSIHANDLE rather than a Database MSIHANDLE. That's why you
have the call MsiGetActiveDatabase from say a custom action because you are
given an Install handle in the MSIHANDLE provided to you. In addition the
active install database is read-only except for temporary rows/tables so
that's probably why you views are failing since you are likely trying to
modify them -- check the error are you getting to be sure.
To make a transform with all latest patches in place in the original
database I would:
1. Locate Cached MSI (or original msi) and copy it to temp -- call it
MSI_orig
2. Update MSI_a with instance ProductCode and close it. Then open with
MsiOpenPackage as hProduct.
3. Get the active Database from this Product Handle -- call it MSI_a. At
this point you should have read-only copy of patched/transformed MSI for the
product you want.
4. Create new empty database using MSIDBOPEN_CREATEDIRECT is fine -- call it
MSI_b
5. Enumerate contents of `_Tables` table from MSI_a, then
Export each table found to IDT file and import into MSI_b (using
MsiDatabaseExport/MsiDatabaseImport)
Export/Import _SummaryInformation table
6. Commit and close Handles
The up-to-date MSI_b file should now be available for copying/modification
and suitable for creating a transform.
Sincerely,
Adrian Accinelli