cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Lou_Elston
Level 6

MsiEnableLog VB problem

Someone had previously given me this code, so that I could display more information to the user (instead of just seeing the Vista processing circle), when we were executing multiple .msi files from within a VB6 executable. It did not have logging, and I have added this (from what I can find on-line). The problems are the following. First, the log file is created, but only 1 byte (if you run the installer without the vb exe, the log file is very large). Second, when the second msi is being executed, the first log file disappears (there are named differently). Third, when the exe is done executing (both installer have been run, and I can find the products in Add Remove programs), there are no logs left. What is causing the logs to disappear?

This is called by... InstallMsi ("setup\Product_Master_Install.msi")

Which calls the code in this module...

Attribute VB_Name = "Module1"
Option Explicit


Public Const ERROR_SUCCESS = 0
Private Const IDOK = 1
Private Const IDCANCEL = 2
Public sLogPath As String

Private Enum INSTALLUILEVEL
INSTALLUILEVEL_NOCHANGE = 0
INSTALLUILEVEL_DEFAULT = 1
INSTALLUILEVEL_NONE = 2
INSTALLUILEVEL_BASIC = 3
INSTALLUILEVEL_REDUCED = 4
INSTALLUILEVEL_FULL = 5
INSTALLUILEVEL_HIDECANCEL = &H20&
INSTALLUILEVEL_PROGRESSONLY = &H40&
INSTALLUILEVEL_ENDDIALOG = &H80&
INSTALLUILEVEL_SOURCERESONLY = &H100&
End Enum

Private Enum INSTALLLOGMODE
INSTALLLOGMODE_FATALEXIT = &H1&
INSTALLLOGMODE_ERROR = &H2&
INSTALLLOGMODE_WARNING = &H4&
INSTALLLOGMODE_USER = &H8&
INSTALLLOGMODE_INFO = &H10&
INSTALLLOGMODE_FILESINUSE = &H20&
INSTALLLOGMODE_RESOLVESOURCE = &H40&
INSTALLLOGMODE_OUTOFDISKSPACE = &H80&
INSTALLLOGMODE_ACTIONSTART = &H100&
INSTALLLOGMODE_ACTIONDATA = &H200&
INSTALLLOGMODE_PROGRESS = &H400&
INSTALLLOGMODE_COMMONDATA = &H800&
INSTALLLOGMODE_INITIALIZE = &H1000&
INSTALLLOGMODE_TERMINATE = &H2000&
INSTALLLOGMODE_SHOWDIALOG = &H4000&
INSTALLLOGMODE_RMFILESINUSE = &H2000000
INSTALLLOGMODE_INSTALLSTART = &H4000000
INSTALLLOGMODE_INSTALLEND = &H8000000
End Enum

Private Enum INSTALLMESSAGE
INSTALLMESSAGE_FATALEXIT = 0
INSTALLMESSAGE_ERROR = &H1000000
INSTALLMESSAGE_WARNING = &H2000000
INSTALLMESSAGE_USER = &H3000000
INSTALLMESSAGE_INFO = &H4000000
INSTALLMESSAGE_FILESINUSE = &H5000000
INSTALLMESSAGE_RESOLVESOURCE = &H6000000
INSTALLMESSAGE_OUTOFDISKSPACE = &H7000000
INSTALLMESSAGE_ACTIONSTART = &H8000000
INSTALLMESSAGE_ACTIONDATA = &H9000000
INSTALLMESSAGE_PROGRESS = &HA000000
INSTALLMESSAGE_COMMONDATA = &HB000000
INSTALLMESSAGE_INITIALIZE = &HC000000
INSTALLMESSAGE_TERMINATE = &HD000000
INSTALLMESSAGE_SHOWDIALOG = &HE000000
INSTALLLOGMODE_VERBOSE = &H4096
End Enum

Private Enum INSTALLLOGATTRIBUTES
INSTALLLOGATTRIBUTES_APPEND = &H1000000
INSTALLLOGATTRIBUTES_FLUSHEACHLINE = &H2000000
End Enum



Private Declare Function MsiSetInternalUI Lib "msi.dll" ( _
ByVal dwUILevel As INSTALLUILEVEL, _
ByRef phWnd As Long) As Long

Private Declare Function MsiSetExternalUIW Lib "msi.dll" ( _
ByVal puiHandler As Long, _
ByVal dwMessageFilter As Long, _
ByVal pvContext As Long) As Long

Private Declare Function MsiInstallProductW Lib "msi.dll" ( _
ByVal szPackagePath As Long, _
ByVal szCommandLine As Long) As Long
Private Declare Sub RtlMoveMemory Lib "Kernel32.dll" ( _
pDest As Any, _
pSrc As Any, _
ByVal ByteLen As Long)

Public Declare Function MsiEnableLog Lib "msi.dll" Alias "MsiEnableLogA" ( _
ByVal dwLogMode As Long, _
ByVal szLogFile As String, _
ByVal dwLogAttributes As Long _
) As Integer

Private Declare Function lstrlenW Lib "Kernel32.dll" ( _
ByVal ptr As Long) As Long


Public Function InstallMsi(ByVal filePath As String) As Long

' Returns zero on successful installation.
Dim dwMsg As Long

On Error GoTo UnexpectedError

' Hides cancel button and only shows progress.
Call MsiSetInternalUI(INSTALLUILEVEL_BASIC Or _
INSTALLUILEVEL_PROGRESSONLY Or _
INSTALLUILEVEL_HIDECANCEL, 0)


dwMsg = INSTALLLOGMODE_FATALEXIT Or _
INSTALLLOGMODE_ERROR Or _
INSTALLLOGMODE_WARNING Or _
INSTALLLOGMODE_USER Or _
INSTALLLOGMODE_INFO Or _
INSTALLLOGMODE_RESOLVESOURCE Or _
INSTALLLOGMODE_OUTOFDISKSPACE


MsiSetExternalUIW AddressOf UIHandlerCallback, dwMsg, 0


Call MsiEnableLog(INSTALLLOGMODE_VERBOSE, sLogPath, INSTALLLOGATTRIBUTES_FLUSHEACHLINE)


InstallMsi = MsiInstallProductW(StrPtr(filePath), 0)



Exit Function

UnexpectedError:
' Describe the error to the user.
MsgBox "Module1 Unexpected error" & _
Str$(Err.Number) & _
vbCrLf & _
Err.Description
End Function

Public Function UIHandlerCallback( _
ByVal pvContext As Long, _
ByVal iMessageType As Long, _
ByVal szMessage As Long) As Long

Dim mt As Long

mt = (&HFF000000 And iMessageType)

Select Case mt
Case INSTALLMESSAGE_FATALEXIT
Debug.Print WidePointerString(szMessage)
Case INSTALLMESSAGE_ERROR
Debug.Print WidePointerString(szMessage)
Case INSTALLMESSAGE_WARNING
Debug.Print WidePointerString(szMessage)
Case INSTALLMESSAGE_USER
Debug.Print WidePointerString(szMessage)
Case INSTALLMESSAGE_INFO
Debug.Print WidePointerString(szMessage)
Case INSTALLMESSAGE_FILESINUSE
Debug.Print WidePointerString(szMessage)
Case INSTALLMESSAGE_RESOLVESOURCE
Debug.Print WidePointerString(szMessage)
Case INSTALLMESSAGE_OUTOFDISKSPACE
Debug.Print WidePointerString(szMessage)
End Select

UIHandlerCallback = 0
End Function

Private Function WidePointerString(ByVal lpPointer As Long) As String
Dim Buffer() As Byte
Dim lpSize As Long
lpSize = lstrlenW(lpPointer) * 2
If lpSize <> 0 Then
ReDim Buffer(lpSize) As Byte
RtlMoveMemory Buffer(0), ByVal lpPointer, lpSize
WidePointerString = Buffer
End If
Erase Buffer
End Function
Labels (1)
0 Kudos
(4) Replies
RobertDickau
Flexera Alumni

I don't have a copy of VB6 around, but it seems this API prototype is the only one using the ANSI signature, where the rest use the wide-char prototype:
Public Declare Function MsiEnableLog Lib "msi.dll" Alias "MsiEnableLogA" 
Does switching to the MsiEnableLogW version change anything?
0 Kudos
Lou_Elston
Level 6

I changed to the W, that did not do the trick. I did a search on W, and found this linik...http://forum.mess.be/lofiversion/index.php/t19838.html. He puts the msienablelog AFTER the execution of the MsiInstallProduct, I do not know why. I tried it, it did not change anything.
0 Kudos
Lou_Elston
Level 6

The msi.h file for vb6 does not include the Verbose flag. So the log file (1KB), would exist for the duration of the execution of the installer, but because it was blank, it would go away when done. I can concatenate all the flags together, but it is nothing like Verbose, as the output log file is much smaller. I will try to convince them to upgrade from VB6 (the only Vb6 program that we have), to C# 2008.
0 Kudos
RobertDickau
Flexera Alumni

Actually, the verbose-flag definition INSTALLLOGMODE_VERBOSE = &H4096 is a bit suspicious (you probably want decimal 4096 and not hex); perhaps just do---

INSTALLLOGMODE_VERBOSE = 4096

or

INSTALLLOGMODE_VERBOSE = &H1000

...?
0 Kudos