Sign in to follow this  
Followers 0
notta

Mutiple MSI's

12 posts in this topic

#1 ·  Posted (edited)

I'm creating a package that uses Msiexec to launch a MSI installer, but the problem is the first MSI launches about 5 other MSI installers during the install process and the RunWait continues prematurely. I have to copy some files after the install is complete into the directory where the application is installed, but it tries to copy too soon. I am sure you guys know what I mean. I don't really want to use sleep because the install process takes a variable amount of time depending on processor speed. I also don't want to use the WinActive because the user may go back to work while the install is running. Any ideas how I can handle this situation? Thanks.

Edited by notta

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

If you know the "ProductCode" of the MSI... I have a function that could return to you the ProductState ... you can poll until the "ProductState" = 5 ... or some other derivative of checking "ProductState"s in some timely manner. Get Product GUID using ORCA or some other means...

here is the API for product state...

$ret = DLLCall("msi.dll","int","MsiQueryProductState","str",$data)

edit: $data would be the product {GUID}

Edited by LarryDalooza

f_mrcleansmalm_77ce002.jpgAutoIt has helped make me wealthy

Share this post


Link to post
Share on other sites

Thanks for the reply Larry. Could you supply me with product state function? I have used Orca before, but the problem is there are 8 MSI's and I don't know in what order any of them are called. This problem has been a real show-stopper. Thanks.

Share this post


Link to post
Share on other sites

The API I posted is all you need.

You need to get the ProductCode {GUID} for every .msi ... then create a While loop that doesn't exit until all MsiQueryProductState s return 5 or whatever state you determine. Have some sort of timeout in your loop so it doesn't loop forever. reset the timeout every time a new msi state changes.

This should be enough to start with... try some stuff... post some code... go from there.

Lar.


f_mrcleansmalm_77ce002.jpgAutoIt has helped make me wealthy

Share this post


Link to post
Share on other sites

I tried using this method but the installer crashed...i believe when it queried the installer...any recomendations?

Share this post


Link to post
Share on other sites

If you know the "ProductCode" of the MSI... I have a function that could return to you the ProductState ... you can poll until the "ProductState" = 5 ... or some other derivative of checking "ProductState"s in some timely manner. Get Product GUID using ORCA or some other means...

here is the API for product state...

$ret = DLLCall("msi.dll","int","MsiQueryProductState","str",$data)

edit: $data would be the product {GUID}

is it possible to read the MSI Productcode with dllcall from MSI File ??

Share this post


Link to post
Share on other sites

Here is one way... to get from .msi file ... it pops up a little msi dialog briefly... there is probably a way to do it otherwise... but that s for you to determine.

#cs
UINT MsiOpenPackage(
  __in   LPCTSTR szPackagePath,
  __out  MSIHANDLE* hProduct
);
#ce
$a = DllCall("msi.dll","uint","MsiOpenPackage","str",@ScriptDir & "\MediaPlayer.msi","int*",0)
#cs
UINT MsiGetProductProperty(
  __in     MSIHANDLE hProduct,
  __in     LPCTSTR szProperty,
  __out    LPTSTR lpValueBuf,
  __inout  DWORD* pcchValueBuf
);
#ce
$b = DllCall("msi.dll","uint","MsiGetProductProperty","int",$a[2],"str","ProductCode","str","","dword*",126)
#cs
UINT MsiCloseHandle(
  __in  MSIHANDLE hAny
);
#ce
DllCall("msi.dll","uint","MsiCloseHandle","int",$a[2])
MsgBox(4096,"",$b[3])

Lar


f_mrcleansmalm_77ce002.jpgAutoIt has helped make me wealthy

Share this post


Link to post
Share on other sites

Hi,

what about waiting for MSIEXEC.EXE to terminate?

while ProcessExists("msiexec.exe")
sleep(100)
WEnd

Regards, Rudi.


Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Share this post


Link to post
Share on other sites

Here is one way... to get from .msi file ... it pops up a little msi dialog briefly... there is probably a way to do it otherwise... but that s for you to determine.

#cs
UINT MsiOpenPackage(
  __in   LPCTSTR szPackagePath,
  __out  MSIHANDLE* hProduct
);
#ce
$a = DllCall("msi.dll","uint","MsiOpenPackage","str",@ScriptDir & "\MediaPlayer.msi","int*",0)
#cs
UINT MsiGetProductProperty(
  __in     MSIHANDLE hProduct,
  __in     LPCTSTR szProperty,
  __out    LPTSTR lpValueBuf,
  __inout  DWORD* pcchValueBuf
);
#ce
$b = DllCall("msi.dll","uint","MsiGetProductProperty","int",$a[2],"str","ProductCode","str","","dword*",126)
#cs
UINT MsiCloseHandle(
  __in  MSIHANDLE hAny
);
#ce
DllCall("msi.dll","uint","MsiCloseHandle","int",$a[2])
MsgBox(4096,"",$b[3])

Lar

@Lar Thanks a lot !!! You are great in DLL Calls

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0