|
-
July 10th, 2012, 10:53 AM
#1
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..
-
July 10th, 2012, 01:53 PM
#2
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.
-
July 11th, 2012, 07:40 AM
#3
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!
-
July 11th, 2012, 08:40 AM
#4
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.
-
July 11th, 2012, 02:35 PM
#5
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!!
-
July 12th, 2012, 03:52 AM
#6
Re: Finding a Memory Leak In Code...???
 Originally Posted by Superfreak3
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.
-
July 12th, 2012, 07:56 AM
#7
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|