I hope someone here can help me. There aren't many Windows Installer patch code examples our there and I get few if any replies to my posts looking for info.
We have an update utility that fires a Windows Installer patch (.msp) if its found in our application's update folder location. Currently it simply attempts to apply the patch if the .msp exists. I would like to change that to check to see if the patch actually needs to be applied.
First, I need the Patch/Product Codes from the .msp then I need to check the need for application against that Product Code. Grabbing the info from the patch seems to be working. It's the application check that is causing problems.
1. Const MinMsiVersion = "3.0" 'Minimum version to support functionality
2. Const MSIPATCHSTATE_APPLIED = 1 'Patch is applied to this product instance.
3. Const msiInstallContextMachine = 4 'Enumerate products that are under the machine account.
4.
5. Dim iInstaller As WindowsInstaller.Installer
6. Dim pPatch 'As WindowsInstaller.Patch
7. '= CreateObject("WindowsInstaller.Installer")
8.
9. Dim strPatchPath, _
10. strPatchCode, _
11. strProdCode As String
12. Dim strPatchXML As String
13. Dim xmlMsiPatch As XmlDocument = New XmlDocument()
14.
15. Try
16. If MinMsiVersion > iInstaller.Version Then
17. MsgBox("Minimum Windows Installer version " & MinMsiVersion & " required. Current version is " & iInstaller.Version, MsgBoxStyle.OkOnly, "Windows Installer version problem...")
18. End If
19.
20. iInstaller = CType(CreateObject("WindowsInstaller.Installer"), _
21. WindowsInstaller.Installer)
22.
23. strPatchPath = "C:\Program Files (x86)\MyComp\Adept80\MyApp\Install\MyAppPatch.msp"
24. strPatchXML = iInstaller.ExtractPatchXMLData(strPatchPath)
25.
26. xmlMsiPatch.LoadXml(strPatchXML)
27.
28. strPatchCode = xmlMsiPatch.DocumentElement.Attributes("PatchGUID").Value
29. strProdCode = xmlMsiPatch.GetElementsByTagName("TargetProductCode").Item(0).InnerText
30.
31. pPatch = iInstaller.Patch(strPatchCode, strProdCode, "", msiInstallContextMachine)
32.
33. If pPatch.State = MSIPATCHSTATE_APPLIED Then 'already applied
34. MsgBox("Write to log... Patch has already been applied (" & pPatch.State & ")!")
35. Else
36. MsgBox("I'm installing the patch")
37. End If
38.
39. Catch ex As Exception
40. MsgBox(Err.Number)
41. MsgBox(Err.Description)
42. 'MsgBox(ex.Message)
43. MsgBox(ex.ToString)
44.
45. 'ERROR_PATCH_NOT_APPLIED
46. End Try
This code is failing on line 31. pPatch = iInstaller.Patch(strPatchCode, strProdCode, "", msiInstallContextMachine). The Error Number is 13 - Return Arguement Has An Invalid Type. Can anyone help me correct this?
I've attached an image containing more info generated from/by this error.
Since all of this may have to be ported to C++ I'm wondering if it would be better to use this code instead...
1. Const MinMsiVersion = "3.0" 'Minimum version to support functionality
2. Const MSIPATCHSTATE_APPLIED = 1 'Patch is applied to this product instance.
3. Const msiInstallContextMachine = 4 'Enumerate products that are under the machine account.
4.
5. Dim iInstaller = CreateObject("WindowsInstaller.Installer")
6.
7. Dim strPatchPath, _
8. strPatchCode, _
9. strProdCode As String
10. Dim strPatchXML As String
11. Dim xmlMsiPatch As XmlDocument = New XmlDocument()
12.
13. Try
14.
15. If MinMsiVersion > iInstaller.Version Then
16. MsgBox("Minimum Windows Installer version " & MinMsiVersion & " required. Current version is " & iInstaller.Version, MsgBoxStyle.OkOnly, "Windows Installer version problem...")
17. End If
18.
19. strPatchPath = "C:\Program Files (x86)\MyComp\MyApp\Client\Install\MyAppPatch.msp"
20. strPatchXML = iInstaller.ExtractPatchXMLData(strPatchPath)
21.
22. xmlMsiPatch.LoadXml(strPatchXML)
23.
24. strPatchCode = xmlMsiPatch.DocumentElement.Attributes("PatchGUID").Value
25. strProdCode = xmlMsiPatch.GetElementsByTagName("TargetProductCode").Item(0).InnerText
26.
27. Dim pPatch = iInstaller.Patch(strPatchCode, strProdCode, "", msiInstallContextMachine)
28.
29. If pPatch.State = MSIPATCHSTATE_APPLIED Then 'already applied
30. MsgBox("Write to log... Patch has already been applied (" & pPatch.State & ")!")
31. Else
32. MsgBox("I'm installing the patch")
33. End If
34.
35. Catch ex As Exception
36. MsgBox(Err.Number)
37. MsgBox(Err.Description)
38. 'MsgBox(ex.Message)
39. MsgBox(ex.ToString)
40.
41. 'ERROR_PATCH_NOT_APPLIED
42. End Try
However this code snippet was failing on...
If pPatch.State = MSIPATCHSTATE_APPLIED Then
The error number I eventually was able to get from it was -21470223249 which after digging a bit I found was ERROR_PATCH_NOT_APPLIED.
I'm not currently able to handle if the patch has not been applied with this code. If the patch is installed, the return, 1, is fine and the log write would occur (in this case msgbox). If not installed or applied, BOOM!
In the first code snipped, these were the imports...
Imports WindowsInstaller Imports System Imports System.Xml
In the second code segment, Windowsinstaller was commented out.
I hope someone can help me as I think/hope I am very close to having some workable code to detect if a patch has been applied!
Thanks in advance for any help!!!

New Topic/Question
Reply



MultiQuote

|