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

    Finding a Memory Leak In Code...???

    Hi all,

    I have an install widget the basically checks the ProductCode of an .msi, checks the registry to see if the product is installed, if not, it monitors msiexec processes and will fire the checked installer when the parent install process has finished.

    When I watch this runnning with Task Manager, it seems that it is eating a ton of the CPU.

    Is there any glaring memory leak in the following code? I'm no expert, and just know enough to get by so any tips would be appreciated...

    Code:
    Imports Microsoft.Win32
    Imports System.Diagnostics
    
    Public Class Form1
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Me.Close()
        End Sub
    
        Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
            Dim strFlag As String = Environment.GetCommandLineArgs.ElementAt(1) '0 element is path to .exe
            Dim strCode As String
    
            If strFlag = "/I" Then
    
                Dim strPath As String = Environment.GetCommandLineArgs.ElementAt(2) '0 element is path to .exe
    
                If Microsoft.VisualBasic.Right(strPath, 1) <> "\" Then
                    strPath = strPath & "\"
                End If
    
                'Get the Product Code and determine if installed...
                strCode = GetProductCode(strPath & "Client\AdeptDWG\Install\RealDWGx64.msi")
    
                If Not FindRelatedProduct(strCode) Then
                    'If not installed, no need to worry about removing earlier versions (different ProductCode) in code.
                    'Removal will be taken care of with Major Upgrade of new RealDWG installer.
    
                    'System.Threading.Thread.Sleep(30000)
                    Call CheckMSIExec()
    
                    Shell("msiexec /qb! /i """ & strPath & "Client\AdeptDWG\Install\RealDWGx64.msi""", AppWinStyle.NormalFocus, False)
                End If
    
                End
            Else 'Uninstall RealDWG
                Call RemoveRealDWG()
                End
            End If
    
    
        End Sub
    
        Public Function GetProductCode(ByVal msiFile As String) As String
    
            Dim oInstaller As WindowsInstaller.Installer
            Dim oDatabase As WindowsInstaller.Database
            Dim oView As WindowsInstaller.View = Nothing
            Dim oRecord As WindowsInstaller.Record
            Dim strSQL As String
            Dim strCode As String
    
            Try
                oInstaller = CType(CreateObject("WindowsInstaller.Installer"), WindowsInstaller.Installer)
                oDatabase = oInstaller.OpenDatabase(msiFile, 0) 'Open Read-Only
                strSQL = "SELECT * FROM `Property` WHERE `Property`='ProductCode'"
    
                oView = oDatabase.OpenView(strSQL)
                oView.Execute()
    
                oRecord = oView.Fetch
    
                strCode = oRecord.StringData(2)
    
                Return strCode
    
            Catch ex As Exception
                'Do Nothing
                MsgBox("[1]: " & ex.Message, MsgBoxStyle.OkOnly, "RealDWGx64 Product Code...")
                End
            Finally
                oRecord = Nothing
                If Not (oView Is Nothing) Then
                    oView.Close()
                End If
                oView = Nothing
                oDatabase = Nothing
                oInstaller = Nothing
            End Try
        End Function
    
        Public Function FindRelatedProduct(ByVal strCode As String) As Boolean
            Dim regKey As RegistryKey
            Dim blnFound As Boolean = False
    
            regKey = Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Uninstall")
    
            For Each key In regKey.GetSubKeyNames
                If key = strCode Then
                    blnFound = True
                End If
            Next
    
            Return blnFound
        End Function
    
        Public Sub RemoveRealDWG()
            Dim regKey, _
                regKeySub As RegistryKey
            Dim strValue As String
    
            regKey = Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Uninstall")
    
            For Each key In regKey.GetSubKeyNames
                regKeySub = Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Uninstall\" & key)
                strValue = regKeySub.GetValue("Comments")
                If strValue = "RealDWG for x64 Adept Client" Then
    
                    'System.Threading.Thread.Sleep(30000)
                    Call CheckMSIExec()
    
                    Shell("msiexec /qb! /x " & key, AppWinStyle.NormalFocus, False)
                    End
    
                End If
            Next
        End Sub
    
        Public Sub CheckMSIExec()
    
            'Cycle through running processes and see if MSI engine ready to start RealDWG installer...
            Dim procList() As Process = Process.GetProcesses
            Dim i As Integer
            Dim intCount As Integer = 0
    
            For i = 0 To procList.Count - 1
                If InStr(UCase(procList(i).ProcessName), "MSIEXEC") > 0 Then
                    intCount = intCount + 1
                End If
            Next
    
            If intCount > 1 Then
                Call CheckMSIExec()
            End If
    
        End Sub
    End Class
    Everything works as I would like as coded, but there is a delay so something seems to have the need to be streamlined.

    Again, any help is Greatly Appreciated!
    Last edited by GremlinSA; July 10th, 2012 at 12:29 PM. Reason: Added Code tags..

  2. #2
    Join Date
    Jun 2005
    Location
    JHB South Africa
    Posts
    3,772

    Re: Finding a Memory Leak In Code...???

    Code:
        Public Sub CheckMSIExec()
    
            'Cycle through running processes and see if MSI engine ready to start RealDWG installer...
            Dim procList() As Process = Process.GetProcesses
            Dim i As Integer
            Dim intCount As Integer = 0
    
            For i = 0 To procList.Count - 1
                If InStr(UCase(procList(i).ProcessName), "MSIEXEC") > 0 Then
                    intCount = intCount + 1
                End If
            Next
    
            If intCount > 1 Then
                Call CheckMSIExec()
            End If
    
        End Sub
    The highlighted code is your problem.. It recursively calls itself until 'MSIEXEC' is not running anymore.. There are no pauses in the code, and also every recursive call increases the stack, increasing memory usage...

    You'll need to rethink this code...
    Articles VB6 : Break the 2G limit - Animation 1, 2 VB.NET : 2005/8 : Moving Images , Animation 1 , 2 , 3 , User Controls
    WPF Articles : 3D Animation 1 , 2 , 3
    Code snips: VB6 Hex Edit, IP Chat, Copy Prot., Crop, Zoom : .NET IP Chat (V4), Adv. ContextMenus, click Hotspot, Scroll Controls
    Find me in ASP.NET., VB6., VB.NET , Writing Articles, My Genealogy, Forum
    All VS.NET: posts refer to VS.NET 2008 (Pro) unless otherwise stated.

  3. #3
    Join Date
    Mar 2010
    Posts
    15

    Re: Finding a Memory Leak In Code...???

    The CheckMSIExec code was the problem. I changed that to a boolean function that returns True (still running) or false (OK to start other msi process).

    I call this from a Do Until loop that contains a sleep for a second or two then a call to the function. It seems to have remedied the problem.

    Thanks!

  4. #4
    Join Date
    Jun 2005
    Location
    JHB South Africa
    Posts
    3,772

    Re: Finding a Memory Leak In Code...???

    while not perfect, your solution is 100% better than what you had..

    Articles VB6 : Break the 2G limit - Animation 1, 2 VB.NET : 2005/8 : Moving Images , Animation 1 , 2 , 3 , User Controls
    WPF Articles : 3D Animation 1 , 2 , 3
    Code snips: VB6 Hex Edit, IP Chat, Copy Prot., Crop, Zoom : .NET IP Chat (V4), Adv. ContextMenus, click Hotspot, Scroll Controls
    Find me in ASP.NET., VB6., VB.NET , Writing Articles, My Genealogy, Forum
    All VS.NET: posts refer to VS.NET 2008 (Pro) unless otherwise stated.

  5. #5
    Join Date
    Mar 2010
    Posts
    15

    Re: Finding a Memory Leak In Code...???

    If there is an even better way to do it, please let me know. It's only a little widget run from an installer so I don't know how robust it has to/should be.

    THANKS!!

  6. #6
    Join Date
    Jun 2005
    Location
    JHB South Africa
    Posts
    3,772

    Re: Finding a Memory Leak In Code...???

    Quote Originally Posted by Superfreak3 View Post
    If there is an even better way to do it, please let me know.
    The best method is always according to personal preference, and no two Guru's will always agree on the same method..

    The Ideal method would involve Worker thread's and some API calls, which some may call overkill... But for your level of knowledge, what you've done is fine, and it's easier for you to debug in future. Threading and API's are a bugger to debug if you've never been into the inner sanctum of a Processor..
    Last edited by GremlinSA; July 12th, 2012 at 03:53 AM. Reason: fixed grammer
    Articles VB6 : Break the 2G limit - Animation 1, 2 VB.NET : 2005/8 : Moving Images , Animation 1 , 2 , 3 , User Controls
    WPF Articles : 3D Animation 1 , 2 , 3
    Code snips: VB6 Hex Edit, IP Chat, Copy Prot., Crop, Zoom : .NET IP Chat (V4), Adv. ContextMenus, click Hotspot, Scroll Controls
    Find me in ASP.NET., VB6., VB.NET , Writing Articles, My Genealogy, Forum
    All VS.NET: posts refer to VS.NET 2008 (Pro) unless otherwise stated.

  7. #7
    Join Date
    Mar 2010
    Posts
    15

    Re: Finding a Memory Leak In Code...???

    Cool! Thanks for information!!

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