CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Mar 2010
    Posts
    15

    Problems Determining Patch Application State...

    I hope someone can help me here. There aren't many good code examples out there dealing with Windows Installer patches (.msp). We have an update widget that will install or apply a patch simply if the .msp is located in the application's update folder location. I want to try to change that to first, determine if the patch actually needs to be applied.

    First, I need to grab the Patch/Product codes from the .msp, then check the Patch.State against the Product Code. The first part is working fine, but I'm having problems checking the State...

    Code:
    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 with an error 13 - Return Argument Has An Invalid Type. Can anyone help get me around this? I've attached an image with some more info from this error.

    Since all of this may have to be ported to C++, I wonder if its better to try to get the following code up and running...

    Code:
    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!!!

    THANKS FOR YOUR HELP!!
    Attached Images Attached Images  

  2. #2
    Join Date
    Jan 2006
    Location
    Fox Lake, IL
    Posts
    15,007

    Re: Problems Determining Patch Application State...

    Might want to look into POWERSHELL to write a script
    David

    CodeGuru Article: Bound Controls are Evil-VB6
    2013 Samples: MS CODE Samples

    CodeGuru Reviewer
    2006 Dell CSP
    2006, 2007 & 2008 MVP Visual Basic
    If your question has been answered satisfactorily, and it has been helpful, then, please, Rate this Post!

  3. #3
    Join Date
    Mar 2010
    Posts
    15

    Re: Problems Determining Patch Application State...

    Our update widget is currently an old C++ app. I just want to get it to work first in VB.NET, but I think we'll port it to C++ eventually.

    I'm not going to worry too much about updating all the other widget code because hopefully, we'll be phasing it out and moving to a Group Policy deployment widget.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured