HRESULT CpiActionStartMessage( LPWSTR* ppwzActionData, BOOL fSuppress ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hRec; LPWSTR pwzData = NULL; // create record hRec = ::MsiCreateRecord(3); ExitOnNull(hRec, hr, E_OUTOFMEMORY, "Failed to create record"); // action name hr = WcaReadStringFromCaData(ppwzActionData, &pwzData); ExitOnFailure(hr, "Failed to action name"); er = ::MsiRecordSetStringW(hRec, 1, pwzData); ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set action name"); // description hr = WcaReadStringFromCaData(ppwzActionData, &pwzData); ExitOnFailure(hr, "Failed to description"); er = ::MsiRecordSetStringW(hRec, 2, pwzData); ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set description"); // template hr = WcaReadStringFromCaData(ppwzActionData, &pwzData); ExitOnFailure(hr, "Failed to template"); er = ::MsiRecordSetStringW(hRec, 3, pwzData); ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set template"); // message if (!fSuppress) { er = WcaProcessMessage(INSTALLMESSAGE_ACTIONSTART, hRec); if (0 == er || IDOK == er || IDYES == er) { hr = S_OK; } else if (IDABORT == er || IDCANCEL == er) { WcaSetReturnValue(ERROR_INSTALL_USEREXIT); // note that the user said exit hr = S_FALSE; } else hr = E_UNEXPECTED; } LExit: // clean up ReleaseStr(pwzData); return hr; }
/******************************************************************** WcaSetComponentState() - sets the install state of a Component ********************************************************************/ extern "C" HRESULT WIXAPI WcaSetComponentState( __in_z LPCWSTR wzComponent, __in INSTALLSTATE isState ) { UINT er = ::MsiSetComponentStateW(WcaGetInstallHandle(), wzComponent, isState); if (ERROR_INSTALL_USEREXIT == er) { WcaSetReturnValue(er); } return HRESULT_FROM_WIN32(er); }
/******************************************************************** WcaProcessMessage() - sends a message from the CustomAction ********************************************************************/ extern "C" UINT WIXAPI WcaProcessMessage( __in INSTALLMESSAGE eMessageType, __in MSIHANDLE hRecord ) { UINT er = ::MsiProcessMessage(WcaGetInstallHandle(), eMessageType, hRecord); if (ERROR_INSTALL_USEREXIT == er || IDCANCEL == er) { WcaSetReturnValue(ERROR_INSTALL_USEREXIT); } return er; }
HRESULT CpiActionDataMessage( DWORD cArgs, ... ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hRec; va_list args; // record hRec = ::MsiCreateRecord(cArgs); ExitOnNull(hRec, hr, E_OUTOFMEMORY, "Failed to create record"); va_start(args, cArgs); for (DWORD i = 1; i <= cArgs; i++) { LPCWSTR pwzArg = va_arg(args, WCHAR*); if (pwzArg && *pwzArg) { er = ::MsiRecordSetStringW(hRec, i, pwzArg); ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set record field string"); } } va_end(args); // message er = WcaProcessMessage(INSTALLMESSAGE_ACTIONDATA, hRec); if (0 == er || IDOK == er || IDYES == er) { hr = S_OK; } else if (IDABORT == er || IDCANCEL == er) { WcaSetReturnValue(ERROR_INSTALL_USEREXIT); // note that the user said exit hr = S_FALSE; } else hr = E_UNEXPECTED; LExit: return hr; }
/******************************************************************** WcaProgressMessage() - extends the progress bar or sends a progress update from the CustomAction ********************************************************************/ extern "C" HRESULT WIXAPI WcaProgressMessage( __in UINT uiCost, __in BOOL fExtendProgressBar ) { static BOOL fExplicitProgressMessages = FALSE; HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; MSIHANDLE hRec = ::MsiCreateRecord(3); // if aren't extending the progress bar and we haven't switched into explicit message mode if (!fExtendProgressBar && !fExplicitProgressMessages) { AssertSz(::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_SCHEDULED) || ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_COMMIT) || ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK), "can only send progress bar messages in a deferred CustomAction"); // tell Darwin to use explicit progress messages ::MsiRecordSetInteger(hRec, 1, 1); ::MsiRecordSetInteger(hRec, 2, 1); ::MsiRecordSetInteger(hRec, 3, 0); er = WcaProcessMessage(INSTALLMESSAGE_PROGRESS, hRec); if (0 == er || IDOK == er || IDYES == er) { hr = S_OK; } else if (IDABORT == er || IDCANCEL == er) { WcaSetReturnValue(ERROR_INSTALL_USEREXIT); // note that the user said exit ExitFunction1(hr = S_FALSE); } else { hr = E_UNEXPECTED; } ExitOnFailure(hr, "failed to tell Darwin to use explicit progress messages"); fExplicitProgressMessages = TRUE; } #if DEBUG else if (fExtendProgressBar) // if we are extending the progress bar, make sure we're not deferred { AssertSz(!::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_SCHEDULED), "cannot add ticks to progress bar length from deferred CustomAction"); } #endif // send the progress message ::MsiRecordSetInteger(hRec, 1, (fExtendProgressBar) ? 3 : 2); ::MsiRecordSetInteger(hRec, 2, uiCost); ::MsiRecordSetInteger(hRec, 3, 0); er = WcaProcessMessage(INSTALLMESSAGE_PROGRESS, hRec); if (0 == er || IDOK == er || IDYES == er) { hr = S_OK; } else if (IDABORT == er || IDCANCEL == er) { WcaSetReturnValue(ERROR_INSTALL_USEREXIT); // note that the user said exit hr = S_FALSE; } else { hr = E_UNEXPECTED; } LExit: if (hRec) { ::MsiCloseHandle(hRec); } return hr; }