Video Screencast Help
Search Video Help Close Back
to help
New in the Rewards Catalog: Vouchers for "Symantec Technical Specialist" and "Symantec Certified Specialist" exams.

Writing to the log file on failures.

Updated: 21 May 2010 | 23 comments
CygnusX1's picture
0 0 Votes
Login to vote
This issue has been solved. See solution.

I am trying to write information to the log file when the installation/uninstallation fails.  I can write the information no problem with a CA with a InstallExecuteSequence of -3.
with this CA....
Function Write2Log(Message)
Const msiMessageTypeInfo = &H04000000
Set oRecord = Installer.CreateRecord(1)
oRecord.StringData(1) = Message
Message msiMessageTypeInfo, oRecord
End Function

How would I go about adding the ProductName and ProductVersion or other properties to the log?  I have tried
various things with oRecord.StringData(0) = and also with FormatRecord all with no luck.
Also, how would I add more error information to the log?  For instance I want to show Insufficient disk space  and
resolve source errors?  Does msiMessageTypeInfo cover all of these?
 

discussion Filed Under:

Comments

EdT's picture
18
May
2009
1 Vote +1
Login to vote

Use Session.Property

The method:

var = session.property("ProductName")

will place the contents of the ProductName property in the variable var - you can then do with it whatever you need to.

If your issue has been solved, please use the "Mark as Solution" link on the most relevant thread.

CygnusX1's picture
18
May
2009
0 Votes 0
Login to vote

That's just it.  I have

That's just it.  I have tried:

Function Write2Log(Message)
DIm sPC
sPN = Property"ProductName")
Const msiMessageTypeInfo = &H04000000
Set oRecord = Installer.CreateRecord(1)
oRecord.StringData(0)=sPN
oRecord.StringData(1) = Message
Message msiMessageTypeInfo, oRecord
End Function

The ProductName never gets written only the error does.  I have tried different variations of oRecord with none of them getting written.
i.e.
Set oRecord = Installer.CreateRecord(2)
oRecord.StringData(0)="Log: [1] [2]"
oRecord.StringData(1) = Property("ProductName")
oRecord.StringData(2) = Message

It seems I can never get the record to be written to the log.

AngelD's picture
18
May
2009
0 Votes 0
Login to vote

You need to use the Session

You need to use the Session object, ex.
oRecord.StringData(1) = Session.Property("ProductName")


EdT's picture
19
May
2009
0 Votes 0
Login to vote

I don't think you do

Kim,
I recall reading that you don't actually need the session object when running vbscript, in, say, the embedded custom action, as the session is implied.

So you can use property("PROPERTYNAME") instead of session.property("PROPERTYNAME"), and I believe I've done that in the past, to remain within the 256 char limit of a Type 38 CA.

However, just in case the session object is undefined at this point in the sequence, it would be sensible to put it in, as well as correcting the syntax error above:  sPN = Property"ProductName") - which should read:  sPN = Property("ProductName")

If your issue has been solved, please use the "Mark as Solution" link on the most relevant thread.

VBScab's picture
19
May
2009
0 Votes 0
Login to vote

...so it should actually read

...so it should actually read:

sPN = Session.Property("ProductName")

Right? :)

Don't know why 'x' happened? Want to know why 'y' happened? Use ProcMon and it will tell you.
Think about using http://www.google.com before posting.

CygnusX1's picture
19
May
2009
0 Votes 0
Login to vote

Session is not needed; but

Session is not needed; but for grins I added it with the same results.
Let me reiterate what I want to do.  Our company policy has Windows Installer logging turned off.
I want to write to the log file on errors only.  I have a vbscript CA placed in the InstallExecuteSequence with a sequence of -3.  The log file gets written to only on errors but only the description of the error is written.  I would like to write additional information to the log file i.e. Product name, version, etc..
Additionally, I would like to write other errors as well: i.e. File in use, insufficent disk space, etc..

Here is the script:
Function msiLog(Message)
Dim sPN
sPN = Session.Property("ProductName")
Const msiMessageTypeInfo = &H04000000
Set oRecord = Installer.CreateRecord(1)
oRecord.StringData(0) = sPN
oRecord.StringData(1) = Message

Message msiMessageTypeInfo,oRecord
Set Record = Nothing
End Function

Here is the log file:
Error 1720. There is a problem with this Windows Installer package. A script required for this install to complete could not be run. Contact your support personnel or package vendor. Custom action DOTNETREGISTER script error -2146828279, Microsoft VBScript runtime error: Subscript out of range: '[number: 2]' Line 5, Column 1,
=== Logging stopped: 5/19/2009 8:12:08 ===

VBScab's picture
19
May
2009
0 Votes 0
Login to vote

Here's a snippet from my

Here's a snippet from my 'Say' subroutine. Build your entire message text, including your ProductName etc., and pass it in to strMsgText (no *&^%$£ CODE tag on this ridiculous forum!) [code]

Sub Say (ByVal strMsgText)
Dim objMSIRecord
Const msiMessageTypeFatalExit = &H00000000 '// Premature termination, possibly fatal out of memory.
Const msiMessageTypeError = &H01000000 '// Formatted error message, [1] is message number in Error table.
Const msiMessageTypeWarning = &H02000000 '// Formatted warning message, [1] is message number in Error table.
Const msiMessageTypeUser = &H03000000 '// User request message, [1] is message number in Error table.
Const msiMessageTypeInfo = &H04000000 '// Informative message for log, not to be displayed.
Const msiMessageTypeFilesInUse = &H05000000 '// List of files in use that need to be replaced.
Const msiMessageTypeResolveSource = &H06000000 '// Request to determine a valid source location.
Const msiMessageTypeOutOfDiskSpace = &H07000000 '// Insufficient disk space message.
Const msiMessageTypeActionStart = &H08000000 '// Start of action,
'// [1] action name,
'// [2] description,
'// [3] template for ACTIONDATA messages.
Const msiMessageTypeActionData = &H09000000 '// Action data. Record fields correspond to the template of ACTIONSTART message.
Const msiMessageTypeProgress = &H0A000000 '// Progress bar information. See the description of record fields below.
Const msiMessageTypeCommonData = &H0B000000 '// To enable the Cancel button set [1] to 2 and [2] to 1.
'// To disable the Cancel button set [1] to 2 and [2] to 0

Set objMSIRecord = Session.Installer.CreateRecord(0)
objMSIRecord.StringData(0) = strMsgText
Session.Message msiMessageTypeError, objMSIRecord
Set objMSIRecord = Nothing
End Sub[/code]

Don't know why 'x' happened? Want to know why 'y' happened? Use ProcMon and it will tell you.
Think about using http://www.google.com before posting.

CygnusX1's picture
19
May
2009
0 Votes 0
Login to vote

used your code verbatim with

used your code verbatim with what was passed to the Sub displayed in a message box and nothing written to the log file. The question is can a package override the logging policy and write to the log file?  If the logging policy was set to just "u"; can a package write the error as well?  Or will the policy override?

VBScab's picture
19
May
2009
0 Votes 0
Login to vote

You can set the logging value

You can set the logging value (as I discovered today!) using the Installer object so, even if there was a policy, your script could override it. Look up 'Installer.EnableLog'  on MSDN.

A message box, you say? Weird...maybe I get only log entries because all the installs at my client are silent. What happens in a silent install?

Don't know why 'x' happened? Want to know why 'y' happened? Use ProcMon and it will tell you.
Think about using http://www.google.com before posting.

CygnusX1's picture
19
May
2009
0 Votes 0
Login to vote

Silently did add strMsgText

Silently did add strMsgText to the log but not the error.

I have been playing around with EnableLog with no vavorable results.  I will post more tomorrow.

John McFadyen's picture
19
May
2009
0 Votes 0
Login to vote

scripts

I use these two regularly

A simple little routine to write to the MSI log.

function WriteToMsiLog(strMessage)
 Const msiMessageTypeInfo = &H04000000
 Set objMessage = session.Installer.CreateRecord(1)
 objMessage.StringData(0) = "Log: [1]"
 objMessage.StringData(1) = strMessage
 if session.property("CUSTDEBUG") <> "" then msgbox "MESSAGE: " & strMessage
 Session.Message msiMessageTypeInfo, objMessage
end function

How to Format Records such as [#FileKey], [$ComponentKey]

function FormatRecord(strRecordName)
on error resume next
set objInstaller = session.installer
set objRecord = objInstaller.CreateRecord(1)
objRecord.ClearData
objRecord.StringData(0) = strRecordName
strFormattedRecord = Session.FormatRecord(objRecord)
WriteToMsiLog "MESSAGE: Formatting record key " & strRecordName & vbcr & "Result = " & strFormattedRecord
FormatRecord = strFormattedRecord
set objRecord = nothing
end function

Intention of how these were written are:

WriteToMsiLog "My message goes here " & session.property("ProductName")

or

FormatRecord "[#FormattedFileRecord]"

EdT's picture
20
May
2009
0 Votes 0
Login to vote

John....

Does your script work when MSI logging is not enabled?
That is what the O/P is trying to achieve.

If your issue has been solved, please use the "Mark as Solution" link on the most relevant thread.

EdT's picture
20
May
2009
0 Votes 0
Login to vote

CygnusX1...

Don't know if this suggestion is a viable alternative to writing to an MSI log, but what about writing to the application EVENT log instead ??

If your issue has been solved, please use the "Mark as Solution" link on the most relevant thread.

CygnusX1's picture
20
May
2009
0 Votes 0
Login to vote

Event log would work just as well...

Event log would work just as well as long as I can write the error somewhere for troubleshooting.  How would I capture the error?  LastErrorRecord does not happen on custom actions. 
As it stands now, when there is an installation error the SMS team asks me for assistance; and in return I ask them to generate a log file.  We need to be proactive and troubleshoot at the time of the error. 
John, I found your example on a Google but unfortunately no information is getting to the log file.  with or without logging fully enabled.  Maybe it is the sequence of -3 that is incorrect?

VBScab's picture
20
May
2009
0 Votes 0
Login to vote

Event Logging is accessed

Event Logging is accessed using the LogEvent method of the WScript.Shell class. Plenty of samples around, esp. at www.computerperformance.co.uk

Don't know why 'x' happened? Want to know why 'y' happened? Use ProcMon and it will tell you.
Think about using http://www.google.com before posting.

CygnusX1's picture
20
May
2009
0 Votes 0
Login to vote

how to capture the error?

event log is no problem; but how do I capture the error itself to throw into the log?  i.e. 1720 error

EdT's picture
21
May
2009
0 Votes 0
Login to vote

I wonder if that is possible

In order to trap the 1720 error, you would somehow need to intercept the custom action call that returns the error - or have some sort of "wrapper" script around your custom action, that grabs the return error code and logs it, before allowing the MSI to rollback.

Frankly, it looks like you are trying to re-engineer windows installer, just because you don't routinely log installs. Maybe the answer is to enable logging, allowing Windows Installer to report on what is happening, and then add some code to nuke the log files if the application installs successfully.

If your issue has been solved, please use the "Mark as Solution" link on the most relevant thread.

CygnusX1's picture
21
May
2009
0 Votes 0
Login to vote

That is the answer that I

That is the answer that I gave management.  Thought I would try and learn some things on the way.

EdT's picture
21
May
2009
0 Votes 0
Login to vote

I should have guessed....

Some questions we get are so far over the "DumbAss" threshold that we can spot straight away that they've come from a management level.
This one didn't quite reach that level - it just sounded plausible....;-)

If your issue has been solved, please use the "Mark as Solution" link on the most relevant thread.

vb_be's picture
24
Sep
2009
0 Votes 0
Login to vote

Thanks a lot to All. I have a

Thanks a lot to All.

I have a requirement to add custom message in the msi log based on the success/failure of installation/update/uninstallation with information/warning/error strings.

I am thinking of the way to find the success or failure of the installation. This thread helped me to add custom action to put appropriate message using VB CA by sequencing with -1/-3.

Thanks,
Vishnu

EdT's picture
24
Sep
2009
0 Votes 0
Login to vote

Are you asking a question?

Or just letting us know that you created a custom action to write in the MSI log whether the installation was successful?? (Which is already reported in the MSI log without needing further coding).

Perhaps if you gave us some additional information on what you did?

If your issue has been solved, please use the "Mark as Solution" link on the most relevant thread.

vb_be's picture
24
Sep
2009
0 Votes 0
Login to vote

Not a question, thanked for the information

Yes, Windows Installer will report installation success or failure in the log. But the logging message by will differ for fresh & patch installation.
But our wrapper program which invokes MSI & MSP looks for specific string (Installation operation completed successfully) in the log file, which will be added by Windows Installer only for fresh installation and for patch installation, it has different string.

Right now, we are delivering only the MSP and not the wrapper program, hence to avoid confusion with customers, I need to write message (Installation operation completed successfully) in the installer log, if msp installation was successful. So I am searching for a way to know whether patch installation succedded or failed.

This thread helped me to create a CA with sequence -1 to write that string to log.

Is this the safe way (using the sequence -1) to look for installation success?

VBScab's picture
25
Sep
2009
0 Votes 0
Login to vote

There's a much better way

>Is this the safe way (using the sequence -1) to look for installation success?
No. Use the Patch property of the Installer object. Details msdn.microsoft.com/en-us/library/aa370594%28VS.85%29.aspx

Don't know why 'x' happened? Want to know why 'y' happened? Use ProcMon and it will tell you.
Think about using http://www.google.com before posting.