int OnExternalUI(IntPtr context, uint messageType, string message) { MsiInstallMessage msgType = (MsiInstallMessage)(MsiInterop.MessageTypeMask & messageType); return(OnMessage(message, msgType)); }
/// <summary> /// Called when MSI message is received. It is actual the MSI <c>Message Loop</c>. /// </summary> /// <param name="message">The message data.</param> /// <param name="messageType">Type of the message.</param> /// <returns>The integer as per MSI documentation.</returns> protected virtual int OnMessage(string message, MsiInstallMessage messageType) { try { switch (messageType) { case MsiInstallMessage.ActionData: this.OnActionData(message); return((int)DialogResult.OK); case MsiInstallMessage.ActionStart: this.CurrentActionName = message.Substring(message.LastIndexOf(".") + 1); return((int)DialogResult.OK); case MsiInstallMessage.CommonData: string[] data = MsiParser.ParseCommonData(message); if (data != null && data[0] != null) { switch (data.MSI <int>(1)) { case 0: // language { Language = data.MSI <int>(2); CodePage = data.MSI <int>(3); } break; case 1: // caption { Caption = data.MSI <string>(2); } break; case 2: // CancelShow { CanCancel = data.MSI <int>(2) == 1; } break; default: break; } } return((int)DialogResult.OK); case MsiInstallMessage.Error: OnError(message, false, MsiInstallMessage.Error); return(1); case MsiInstallMessage.FatalExit: OnError(message, true, MsiInstallMessage.FatalExit); return(1); case MsiInstallMessage.FilesInUse: // display in use files in a dialog, informing the user // that they should close whatever applications are using // them. You must return the DialogResult to the service // if displayed. { //If locked files need to be reported to the user then MsiSetExternalUIRecord should be used OnError("Files in use", true, MsiInstallMessage.FilesInUse); return(0); // we didn't handle it in this case! } case MsiInstallMessage.Info: this.OnInfo(message); return(1); case MsiInstallMessage.Initialize: return(1); case MsiInstallMessage.OutOfDiskSpace: { OnError("Out Of Disk Space", true, MsiInstallMessage.OutOfDiskSpace); break; } case MsiInstallMessage.Progress: { string[] fields = MsiParser.ParseProgressString(message); if (null == fields || null == fields[0]) { return((int)DialogResult.OK); } switch (fields.MSI <int>(1)) { case 0: // reset progress bar { ProgressTotal = fields.MSI <int>(2); IsProgressForwardDirection = fields.MSI <int>(3) == 0; IsProgressTimeEstimationAccurate = fields.MSI <int>(4) == 0; ProgressCurrentPosition = IsProgressForwardDirection ? 0 : ProgressTotal; } break; case 1: // action info { if (this.ProgressTotal == 0) { return((int)DialogResult.OK); //The external handler should not act upon any of these messages until the first a Reset progress message is received. } if (fields.MSI <int>(3) == 1) { TicksPerActionDataMessage = fields.MSI <int>(2); } } break; case 2: // progress { if (this.ProgressTotal == 0) { return((int)DialogResult.OK); //The external handler should not act upon any of these messages until the first a Reset progress message is received. } if (this.ProgressTotal != 0) //initialized { if (IsProgressForwardDirection) { ProgressCurrentPosition = ProgressCurrentPosition + fields.MSI <int>(2); } else { ProgressCurrentPosition = ProgressCurrentPosition - fields.MSI <int>(2); } } } break; default: break; } if (this.CancelRequested) { return((int)DialogResult.Cancel); } else { return((int)DialogResult.OK); } } case MsiInstallMessage.ResolveSource: return(0); case MsiInstallMessage.ShowDialog: return((int)DialogResult.OK); case MsiInstallMessage.Terminate: return((int)DialogResult.OK); case MsiInstallMessage.User: OnUser(message); return(1); case MsiInstallMessage.Warning: OnWarning(message); return(1); default: break; } } catch (Exception e) { // do something meaningful, but don't re-throw here. OnError("Application error: " + e.ToString(), false); } return(0); }
/// <summary> /// Called when MSI message is received. It is actual the MSI <c>Message Loop</c>. /// </summary> /// <param name="message">The message data.</param> /// <param name="messageType">Type of the message. This value get's combined with MessageIcon and a MessageButtons values. Use /// <see cref="MsiInterop.MessageTypeMask"/> to extract the <see cref="WindowsInstaller.MsiInstallMessage"/> value. /// </param> /// <returns>The integer as per MSI documentation.</returns> protected virtual int OnMessage(string message, uint messageType) { MsiInstallMessage msgType = (MsiInstallMessage)(MsiInterop.MessageTypeMask & messageType); return(OnMessage(message, msgType)); }
public static extern int MsiProcessMessage(Int32 install, MsiInstallMessage type, Int32 record);
/// <summary> /// Called when MSI message is received. It is actual the MSI <c>Message Loop</c>. /// </summary> /// <param name="message">The message data.</param> /// <param name="messageType">Type of the message.</param> /// <returns>The integer as per MSI documentation.</returns> protected virtual int OnMessage(string message, MsiInstallMessage messageType) { try { switch (messageType) { case MsiInstallMessage.ActionData: this.OnActionData(message); return (int)DialogResult.OK; case MsiInstallMessage.ActionStart: this.CurrentActionName = message.Substring(message.LastIndexOf(".") + 1); return (int)DialogResult.OK; case MsiInstallMessage.CommonData: string[] data = MsiParser.ParseCommonData(message); if (data != null && data[0] != null) { switch (data.MSI<int>(1)) { case 0: // language { Language = data.MSI<int>(2); CodePage = data.MSI<int>(3); } break; case 1: // caption { Caption = data.MSI<string>(2); } break; case 2: // CancelShow { CanCancel = data.MSI<int>(2) == 1; } break; default: break; } } return (int)DialogResult.OK; case MsiInstallMessage.Error: OnError(message, false, MsiInstallMessage.Error); return 1; case MsiInstallMessage.FatalExit: OnError(message, true, MsiInstallMessage.FatalExit); return 1; case MsiInstallMessage.FilesInUse: // display in use files in a dialog, informing the user // that they should close whatever applications are using // them. You must return the DialogResult to the service // if displayed. { //If locked files need to be reported to the user then MsiSetExternalUIRecord should be used OnError("Files in use", true, MsiInstallMessage.FilesInUse); return 0; // we didn't handle it in this case! } case MsiInstallMessage.Info: this.OnInfo(message); return 1; case MsiInstallMessage.Initialize: return 1; case MsiInstallMessage.OutOfDiskSpace: { OnError("Out Of Disk Space", true, MsiInstallMessage.OutOfDiskSpace); break; } case MsiInstallMessage.Progress: { string[] fields = MsiParser.ParseProgressString(message); if (null == fields || null == fields[0]) { return (int)DialogResult.OK; } switch (fields.MSI<int>(1)) { case 0: // reset progress bar { ProgressTotal = fields.MSI<int>(2); IsProgressForwardDirection = fields.MSI<int>(3) == 0; IsProgressTimeEstimationAccurate = fields.MSI<int>(4) == 0; ProgressCurrentPosition = IsProgressForwardDirection ? 0 : ProgressTotal; } break; case 1: // action info { if (this.ProgressTotal == 0) return (int)DialogResult.OK; //The external handler should not act upon any of these messages until the first a Reset progress message is received. if (fields.MSI<int>(3) == 1) TicksPerActionDataMessage = fields.MSI<int>(2); } break; case 2: // progress { if (this.ProgressTotal == 0) return (int)DialogResult.OK; //The external handler should not act upon any of these messages until the first a Reset progress message is received. if (this.ProgressTotal != 0) //initialized { if (IsProgressForwardDirection) ProgressCurrentPosition = ProgressCurrentPosition + fields.MSI<int>(2); else ProgressCurrentPosition = ProgressCurrentPosition - fields.MSI<int>(2); } } break; default: break; } if (this.CancelRequested) return (int)DialogResult.Cancel; else return (int)DialogResult.OK; } case MsiInstallMessage.ResolveSource: return 0; case MsiInstallMessage.ShowDialog: return (int)DialogResult.OK; case MsiInstallMessage.Terminate: return (int)DialogResult.OK; case MsiInstallMessage.User: OnUser(message); return 1; case MsiInstallMessage.Warning: OnWarning(message); return 1; default: break; } } catch (Exception e) { // do something meaningful, but don't re-throw here. OnError("Application error: " + e.ToString(), false); } return 0; }
/// <summary> /// Called when Error event occurs (MSI Error message is received or an internal error condition triggered). /// </summary> /// <param name="data">The message data.</param> /// <param name="fatal">if set to <c>true</c> the error is fatal.</param> /// <param name="relatedMessageType">Type of the related message. Note the error may be associated with the internal /// error condition (e.g. exception is raised). </param> public virtual void OnError(string data, bool fatal, MsiInstallMessage? relatedMessageType = null) { //Debug.WriteLine("Error>\t\t" + data); }
//http://msdn.microsoft.com/en-us/library/aa370573%28VS.85%29.aspx private int OnExternalUI(IntPtr context, uint messageType, string message) { MsiInstallMessage msg = (MsiInstallMessage)(MsiInterop.MessageTypeMask & messageType); #if DEBUG WriteLogMessage(string.Format("MSI: {0} {1}", msg, message)); #endif try { switch (msg) { /* Formatted error or info messages. No additional processing is needed by external UI */ case MsiInstallMessage.FatalExit: ErrorMessage fatalErrorMessage = new ErrorMessage(); fatalErrorMessage.SetErrorMessageType(ErrorMessageType.FatalExit); fatalErrorMessage.SetFormattedMessage(message); SendInstallerMessageReceived(fatalErrorMessage, true); return((int)(userActed ? userAction : MsiResponse.OK)); case MsiInstallMessage.Error: if (CheckFileInUseMessage(message) == false) { ErrorMessage errorMessage = new ErrorMessage(); errorMessage.SetErrorMessageType(ErrorMessageType.FatalExit); errorMessage.SetFormattedMessage(message); SendInstallerMessageReceived(errorMessage, true); } return((int)(userActed ? userAction : MsiResponse.OK)); case MsiInstallMessage.Warning: ErrorMessage warningMessage = new ErrorMessage(); warningMessage.SetErrorMessageType(ErrorMessageType.Warning); warningMessage.SetFormattedMessage(message); SendInstallerMessageReceived(warningMessage, true); return((int)(userActed ? userAction : MsiResponse.OK)); case MsiInstallMessage.Info: InformationMessage infoMessage = new InformationMessage(); infoMessage.SetFormattedMessage(message); SendInstallerMessageReceived(infoMessage); Application.DoEvents(); return((int)MsiResponse.OK); case MsiInstallMessage.User: InformationMessage userMessage = new InformationMessage(); userMessage.SetFormattedMessage(message); SendInstallerMessageReceived(userMessage); Application.DoEvents(); return((int)MsiResponse.OK); case MsiInstallMessage.OutOfDiskSpace: Application.DoEvents(); return((int)MsiResponse.OK); /* Windows installer UI sequence messages. ALL THESE MESSAGES (UI SEQUENCE) ARE IGNORED */ case MsiInstallMessage.Terminate: Application.DoEvents(); return((int)MsiResponse.OK); case MsiInstallMessage.Initialize: Application.DoEvents(); return((int)MsiResponse.OK); case MsiInstallMessage.ShowDialog: Application.DoEvents(); return((int)MsiResponse.OK); /* Windows installer messages which need input from the user */ case MsiInstallMessage.ResolveSource: /*The external user interface handler must return 0 and allow Windows Installer to handle the message.*/ Application.DoEvents(); return(0); case MsiInstallMessage.FilesInUse: /*Display files in use message*/ Application.DoEvents(); return(0); case MsiInstallMessage.ActionStart: Process_ActionStart_Message(message); Application.DoEvents(); return((int)(userActed ? userAction : MsiResponse.OK)); case MsiInstallMessage.ActionData: ActionDataMessage actionDataMessage = new ActionDataMessage(); actionDataMessage.SetFormattedMessage(message); SendInstallerMessageReceived(actionDataMessage, true); Application.DoEvents(); return((int)(userActed ? userAction : MsiResponse.OK)); case MsiInstallMessage.CommonData: /****** IGNORED ******/ //int commonDataStatus = Process_CommonData_Message(message); //Application.DoEvents(); //return commonDataStatus; Application.DoEvents(); return((int)MsiResponse.OK); /* Progress bar messages */ case MsiInstallMessage.Progress: bool parsed = Process_Progress_Message(message); Application.DoEvents(); return((int)(parsed ? (userActed ? userAction : MsiResponse.OK) : MsiResponse.OK)); default: break; } } catch (Exception e) { WriteLogMessage("Unknown error occured: " + e.ToString()); } Application.DoEvents(); return(0); }