I am writing program witch runs msi installations silent on background. Using MsiSetExternalUI and MsiSetInternalUI with INSTALLUILEVEL_NONE I can show my progress dialog and catch errors during install:
INT CALLBACK ProgressHandler(LPVOID pvContext, UINT uiMessageType, LPC开发者_如何学GoTSTR szMessage)
{
INSTALLMESSAGE iMessage = (INSTALLMESSAGE)(0xFF000000 & uiMessageType);
if( INSTALLMESSAGE_PROGRESS == iMessage )
ShowProgress(...);
if( INSTALLMESSAGE_FILESINUSE == iMessage )
MessageBox(NULL, szMessage, _T("Files in use"), MB_OK);
}
...
DWORD dwMessageFilter = INSTALLLOGMODE_PROGRESS | INSTALLLOGMODE_FILESINUSE;
MsiSetExternalUI(&ProgressHandler, dwMessageFilter, NULL);
INSTALLUILEVEL pervousUILevel = MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
UINT res = MsiInstallProduct(sPath, NULL);
The problem is that when some files is in use my callback receives INSTALLMESSAGE_FILESINUSE message, but szMessage parameter contains only this text - "The following applications should be closed before continuing the installation:". If I run msi file with full interface there is dialog wit list of programs witch must be closed before installation can continue.
How can I get this list and display it to user when running setup without UI?This thread in the wix-users mailing list suggests using MsiSetExternalUIRecord
instead of MsiSetExternalUI
allows you to retrieve the file names in the fields of the record (corresponding to [1], [2], and so forth). Just watch out for empty ones in the middle. This suggests that these values should be available in szMessage, so I'm unclear why they wouldn't be visible already, unless perhaps they contain a NUL and end the string that way.
精彩评论