Jump to content

Recommended Posts

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
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

Posted

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.

Posted

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

  • 3 weeks later...
Posted

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 ??
Posted

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

  • 2 weeks later...
Posted

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

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...