diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2022-03-18 20:16:07 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2022-03-19 12:07:32 -0500 |
commit | fbc1a73743368211d5d8c7fc0625adf6eb9ca50c (patch) | |
tree | c314d72b4b25afab7a27be664a1bffa5bdd80b3a /src | |
parent | fb54576f1d05e82ba47cd718c4c4f8b3bad624c9 (diff) | |
download | wix-fbc1a73743368211d5d8c7fc0625adf6eb9ca50c.tar.gz wix-fbc1a73743368211d5d8c7fc0625adf6eb9ca50c.tar.bz2 wix-fbc1a73743368211d5d8c7fc0625adf6eb9ca50c.zip |
Add checkpoint so Exe and Msu packages rollback after being cancelled.
Fixes 5950
Diffstat (limited to 'src')
-rw-r--r-- | src/burn/engine/apply.cpp | 93 | ||||
-rw-r--r-- | src/burn/engine/apply.h | 2 | ||||
-rw-r--r-- | src/burn/engine/elevation.cpp | 18 | ||||
-rw-r--r-- | src/burn/engine/engine.mc | 7 | ||||
-rw-r--r-- | src/burn/engine/exeengine.cpp | 37 | ||||
-rw-r--r-- | src/burn/engine/msuengine.cpp | 27 | ||||
-rw-r--r-- | src/burn/engine/package.h | 1 | ||||
-rw-r--r-- | src/burn/test/BurnUnitTest/PlanTest.cpp | 4 | ||||
-rw-r--r-- | src/test/burn/TestBA/TestBA.cs | 25 | ||||
-rw-r--r-- | src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs | 14 |
10 files changed, 171 insertions, 57 deletions
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp index 73b5b396..6af5c040 100644 --- a/src/burn/engine/apply.cpp +++ b/src/burn/engine/apply.cpp | |||
@@ -63,6 +63,7 @@ typedef struct _BURN_EXECUTE_CONTEXT | |||
63 | LPCWSTR wzExecutingPackageId; | 63 | LPCWSTR wzExecutingPackageId; |
64 | DWORD cExecutedPackages; | 64 | DWORD cExecutedPackages; |
65 | DWORD cExecutePackagesTotal; | 65 | DWORD cExecutePackagesTotal; |
66 | BOOL fAbandonedProcess; | ||
66 | } BURN_EXECUTE_CONTEXT; | 67 | } BURN_EXECUTE_CONTEXT; |
67 | 68 | ||
68 | 69 | ||
@@ -322,6 +323,7 @@ static HRESULT ExecutePackageComplete( | |||
322 | __in BURN_VARIABLES* pVariables, | 323 | __in BURN_VARIABLES* pVariables, |
323 | __in LPCWSTR wzPackageId, | 324 | __in LPCWSTR wzPackageId, |
324 | __in BOOL fPackageVital, | 325 | __in BOOL fPackageVital, |
326 | __in BOOL fAbandonedProcess, | ||
325 | __in HRESULT hrOverall, | 327 | __in HRESULT hrOverall, |
326 | __in HRESULT hrExecute, | 328 | __in HRESULT hrExecute, |
327 | __in BOOL fRollback, | 329 | __in BOOL fRollback, |
@@ -369,6 +371,7 @@ extern "C" void ApplyReset( | |||
369 | BURN_PACKAGE* pPackage = pPackages->rgPackages + i; | 371 | BURN_PACKAGE* pPackage = pPackages->rgPackages + i; |
370 | pPackage->hrCacheResult = S_OK; | 372 | pPackage->hrCacheResult = S_OK; |
371 | pPackage->fReachedExecution = FALSE; | 373 | pPackage->fReachedExecution = FALSE; |
374 | pPackage->fAbandonedProcess = FALSE; | ||
372 | pPackage->transactionRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; | 375 | pPackage->transactionRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; |
373 | } | 376 | } |
374 | } | 377 | } |
@@ -715,6 +718,9 @@ extern "C" HRESULT ApplyExecute( | |||
715 | continue; | 718 | continue; |
716 | } | 719 | } |
717 | 720 | ||
721 | context.wzExecutingPackageId = NULL; | ||
722 | context.fAbandonedProcess = FALSE; | ||
723 | |||
718 | // If we are seeking the end of the rollback boundary, skip if this action wasn't it. | 724 | // If we are seeking the end of the rollback boundary, skip if this action wasn't it. |
719 | if (fSeekRollbackBoundaryEnd) | 725 | if (fSeekRollbackBoundaryEnd) |
720 | { | 726 | { |
@@ -2437,6 +2443,9 @@ static HRESULT DoRollbackActions( | |||
2437 | continue; | 2443 | continue; |
2438 | } | 2444 | } |
2439 | 2445 | ||
2446 | pContext->wzExecutingPackageId = NULL; | ||
2447 | pContext->fAbandonedProcess = FALSE; | ||
2448 | |||
2440 | if (BURN_EXECUTE_ACTION_TYPE_CHECKPOINT == pRollbackAction->type) | 2449 | if (BURN_EXECUTE_ACTION_TYPE_CHECKPOINT == pRollbackAction->type) |
2441 | { | 2450 | { |
2442 | if (pRollbackAction->checkpoint.dwId == dwCheckpoint) | 2451 | if (pRollbackAction->checkpoint.dwId == dwCheckpoint) |
@@ -2533,6 +2542,28 @@ LExit: | |||
2533 | return hr; | 2542 | return hr; |
2534 | } | 2543 | } |
2535 | 2544 | ||
2545 | static BOOL ShouldSkipPackage( | ||
2546 | __in BURN_PACKAGE* pPackage, | ||
2547 | __in BOOL fRollback | ||
2548 | ) | ||
2549 | { | ||
2550 | BOOL fSkip = FALSE; | ||
2551 | |||
2552 | if (FAILED(pPackage->hrCacheResult)) | ||
2553 | { | ||
2554 | LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult); | ||
2555 | ExitFunction1(fSkip = TRUE); | ||
2556 | } | ||
2557 | else if (fRollback && pPackage->fAbandonedProcess) | ||
2558 | { | ||
2559 | LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_PACKAGE_WITH_ABANDONED_PROCESS, pPackage->sczId); | ||
2560 | ExitFunction1(fSkip = TRUE); | ||
2561 | } | ||
2562 | |||
2563 | LExit: | ||
2564 | return fSkip; | ||
2565 | } | ||
2566 | |||
2536 | static HRESULT ExecuteRelatedBundle( | 2567 | static HRESULT ExecuteRelatedBundle( |
2537 | __in BURN_ENGINE_STATE* pEngineState, | 2568 | __in BURN_ENGINE_STATE* pEngineState, |
2538 | __in BURN_EXECUTE_ACTION* pExecuteAction, | 2569 | __in BURN_EXECUTE_ACTION* pExecuteAction, |
@@ -2551,13 +2582,13 @@ static HRESULT ExecuteRelatedBundle( | |||
2551 | BURN_RELATED_BUNDLE* pRelatedBundle = pExecuteAction->relatedBundle.pRelatedBundle; | 2582 | BURN_RELATED_BUNDLE* pRelatedBundle = pExecuteAction->relatedBundle.pRelatedBundle; |
2552 | BURN_PACKAGE* pPackage = &pRelatedBundle->package; | 2583 | BURN_PACKAGE* pPackage = &pRelatedBundle->package; |
2553 | 2584 | ||
2554 | if (FAILED(pPackage->hrCacheResult)) | 2585 | Assert(pContext->fRollback == fRollback); |
2586 | |||
2587 | if (ShouldSkipPackage(pPackage, fRollback)) | ||
2555 | { | 2588 | { |
2556 | LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult); | ||
2557 | ExitFunction1(hr = S_OK); | 2589 | ExitFunction1(hr = S_OK); |
2558 | } | 2590 | } |
2559 | 2591 | ||
2560 | Assert(pContext->fRollback == fRollback); | ||
2561 | pContext->wzExecutingPackageId = pPackage->sczId; | 2592 | pContext->wzExecutingPackageId = pPackage->sczId; |
2562 | fBeginCalled = TRUE; | 2593 | fBeginCalled = TRUE; |
2563 | 2594 | ||
@@ -2599,7 +2630,8 @@ static HRESULT ExecuteRelatedBundle( | |||
2599 | LExit: | 2630 | LExit: |
2600 | if (fBeginCalled) | 2631 | if (fBeginCalled) |
2601 | { | 2632 | { |
2602 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 2633 | pPackage->fAbandonedProcess = pContext->fAbandonedProcess; |
2634 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, pPackage->fAbandonedProcess, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | ||
2603 | } | 2635 | } |
2604 | 2636 | ||
2605 | return hr; | 2637 | return hr; |
@@ -2624,6 +2656,9 @@ static HRESULT DoRestoreRelatedBundleActions( | |||
2624 | continue; | 2656 | continue; |
2625 | } | 2657 | } |
2626 | 2658 | ||
2659 | pContext->wzExecutingPackageId = NULL; | ||
2660 | pContext->fAbandonedProcess = FALSE; | ||
2661 | |||
2627 | BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE; | 2662 | BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE; |
2628 | switch (pRestoreRelatedBundleAction->type) | 2663 | switch (pRestoreRelatedBundleAction->type) |
2629 | { | 2664 | { |
@@ -2665,13 +2700,13 @@ static HRESULT ExecuteExePackage( | |||
2665 | BOOL fExecuted = FALSE; | 2700 | BOOL fExecuted = FALSE; |
2666 | BURN_PACKAGE* pPackage = pExecuteAction->exePackage.pPackage; | 2701 | BURN_PACKAGE* pPackage = pExecuteAction->exePackage.pPackage; |
2667 | 2702 | ||
2668 | if (FAILED(pPackage->hrCacheResult)) | 2703 | Assert(pContext->fRollback == fRollback); |
2704 | |||
2705 | if (ShouldSkipPackage(pPackage, fRollback)) | ||
2669 | { | 2706 | { |
2670 | LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult); | ||
2671 | ExitFunction1(hr = S_OK); | 2707 | ExitFunction1(hr = S_OK); |
2672 | } | 2708 | } |
2673 | 2709 | ||
2674 | Assert(pContext->fRollback == fRollback); | ||
2675 | pContext->wzExecutingPackageId = pPackage->sczId; | 2710 | pContext->wzExecutingPackageId = pPackage->sczId; |
2676 | fBeginCalled = TRUE; | 2711 | fBeginCalled = TRUE; |
2677 | 2712 | ||
@@ -2720,7 +2755,8 @@ LExit: | |||
2720 | 2755 | ||
2721 | if (fBeginCalled) | 2756 | if (fBeginCalled) |
2722 | { | 2757 | { |
2723 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 2758 | pPackage->fAbandonedProcess = pContext->fAbandonedProcess; |
2759 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, pPackage->fAbandonedProcess, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | ||
2724 | } | 2760 | } |
2725 | 2761 | ||
2726 | return hr; | 2762 | return hr; |
@@ -2743,13 +2779,13 @@ static HRESULT ExecuteMsiPackage( | |||
2743 | BOOL fExecuted = FALSE; | 2779 | BOOL fExecuted = FALSE; |
2744 | BURN_PACKAGE* pPackage = pExecuteAction->msiPackage.pPackage; | 2780 | BURN_PACKAGE* pPackage = pExecuteAction->msiPackage.pPackage; |
2745 | 2781 | ||
2746 | if (FAILED(pPackage->hrCacheResult)) | 2782 | Assert(pContext->fRollback == fRollback); |
2783 | |||
2784 | if (ShouldSkipPackage(pPackage, fRollback)) | ||
2747 | { | 2785 | { |
2748 | LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult); | ||
2749 | ExitFunction1(hr = S_OK); | 2786 | ExitFunction1(hr = S_OK); |
2750 | } | 2787 | } |
2751 | 2788 | ||
2752 | Assert(pContext->fRollback == fRollback); | ||
2753 | pContext->wzExecutingPackageId = pPackage->sczId; | 2789 | pContext->wzExecutingPackageId = pPackage->sczId; |
2754 | fBeginCalled = TRUE; | 2790 | fBeginCalled = TRUE; |
2755 | 2791 | ||
@@ -2784,7 +2820,8 @@ LExit: | |||
2784 | 2820 | ||
2785 | if (fBeginCalled) | 2821 | if (fBeginCalled) |
2786 | { | 2822 | { |
2787 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 2823 | Assert(!pContext->fAbandonedProcess); |
2824 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, FALSE, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | ||
2788 | } | 2825 | } |
2789 | 2826 | ||
2790 | return hr; | 2827 | return hr; |
@@ -2807,13 +2844,13 @@ static HRESULT ExecuteMspPackage( | |||
2807 | BOOL fExecuted = FALSE; | 2844 | BOOL fExecuted = FALSE; |
2808 | BURN_PACKAGE* pPackage = pExecuteAction->mspTarget.pPackage; | 2845 | BURN_PACKAGE* pPackage = pExecuteAction->mspTarget.pPackage; |
2809 | 2846 | ||
2810 | if (FAILED(pPackage->hrCacheResult)) | 2847 | Assert(pContext->fRollback == fRollback); |
2848 | |||
2849 | if (ShouldSkipPackage(pPackage, fRollback)) | ||
2811 | { | 2850 | { |
2812 | LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult); | ||
2813 | ExitFunction1(hr = S_OK); | 2851 | ExitFunction1(hr = S_OK); |
2814 | } | 2852 | } |
2815 | 2853 | ||
2816 | Assert(pContext->fRollback == fRollback); | ||
2817 | pContext->wzExecutingPackageId = pPackage->sczId; | 2854 | pContext->wzExecutingPackageId = pPackage->sczId; |
2818 | fBeginCalled = TRUE; | 2855 | fBeginCalled = TRUE; |
2819 | 2856 | ||
@@ -2857,7 +2894,8 @@ LExit: | |||
2857 | 2894 | ||
2858 | if (fBeginCalled) | 2895 | if (fBeginCalled) |
2859 | { | 2896 | { |
2860 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 2897 | Assert(!pContext->fAbandonedProcess); |
2898 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, FALSE, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | ||
2861 | } | 2899 | } |
2862 | 2900 | ||
2863 | return hr; | 2901 | return hr; |
@@ -2882,13 +2920,13 @@ static HRESULT ExecuteMsuPackage( | |||
2882 | BOOL fExecuted = FALSE; | 2920 | BOOL fExecuted = FALSE; |
2883 | BURN_PACKAGE* pPackage = pExecuteAction->msuPackage.pPackage; | 2921 | BURN_PACKAGE* pPackage = pExecuteAction->msuPackage.pPackage; |
2884 | 2922 | ||
2885 | if (FAILED(pPackage->hrCacheResult)) | 2923 | Assert(pContext->fRollback == fRollback); |
2924 | |||
2925 | if (ShouldSkipPackage(pPackage, fRollback)) | ||
2886 | { | 2926 | { |
2887 | LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult); | ||
2888 | ExitFunction1(hr = S_OK); | 2927 | ExitFunction1(hr = S_OK); |
2889 | } | 2928 | } |
2890 | 2929 | ||
2891 | Assert(pContext->fRollback == fRollback); | ||
2892 | pContext->wzExecutingPackageId = pPackage->sczId; | 2930 | pContext->wzExecutingPackageId = pPackage->sczId; |
2893 | fBeginCalled = TRUE; | 2931 | fBeginCalled = TRUE; |
2894 | 2932 | ||
@@ -2937,7 +2975,8 @@ LExit: | |||
2937 | 2975 | ||
2938 | if (fBeginCalled) | 2976 | if (fBeginCalled) |
2939 | { | 2977 | { |
2940 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 2978 | pPackage->fAbandonedProcess = pContext->fAbandonedProcess; |
2979 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, pPackage->fAbandonedProcess, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | ||
2941 | } | 2980 | } |
2942 | 2981 | ||
2943 | return hr; | 2982 | return hr; |
@@ -3256,7 +3295,8 @@ LExit: | |||
3256 | 3295 | ||
3257 | if (fBeginCalled) | 3296 | if (fBeginCalled) |
3258 | { | 3297 | { |
3259 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pContext->wzExecutingPackageId, FALSE, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 3298 | Assert(!pContext->fAbandonedProcess); |
3299 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pContext->wzExecutingPackageId, FALSE, FALSE, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | ||
3260 | } | 3300 | } |
3261 | 3301 | ||
3262 | return hr; | 3302 | return hr; |
@@ -3334,6 +3374,14 @@ static int GenericExecuteMessageHandler( | |||
3334 | } | 3374 | } |
3335 | break; | 3375 | break; |
3336 | 3376 | ||
3377 | case GENERIC_EXECUTE_MESSAGE_PROCESS_STARTED: | ||
3378 | pContext->fAbandonedProcess = TRUE; | ||
3379 | break; | ||
3380 | |||
3381 | case GENERIC_EXECUTE_MESSAGE_PROCESS_COMPLETED: | ||
3382 | pContext->fAbandonedProcess = FALSE; | ||
3383 | break; | ||
3384 | |||
3337 | case GENERIC_EXECUTE_MESSAGE_ERROR: | 3385 | case GENERIC_EXECUTE_MESSAGE_ERROR: |
3338 | UserExperienceOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_EXE_PACKAGE, pContext->wzExecutingPackageId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwUIHint, 0, NULL, &nResult); // ignore return value. | 3386 | UserExperienceOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_EXE_PACKAGE, pContext->wzExecutingPackageId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwUIHint, 0, NULL, &nResult); // ignore return value. |
3339 | break; | 3387 | break; |
@@ -3428,6 +3476,7 @@ static HRESULT ExecutePackageComplete( | |||
3428 | __in BURN_VARIABLES* pVariables, | 3476 | __in BURN_VARIABLES* pVariables, |
3429 | __in LPCWSTR wzPackageId, | 3477 | __in LPCWSTR wzPackageId, |
3430 | __in BOOL fPackageVital, | 3478 | __in BOOL fPackageVital, |
3479 | __in BOOL fAbandonedProcess, | ||
3431 | __in HRESULT hrOverall, | 3480 | __in HRESULT hrOverall, |
3432 | __in HRESULT hrExecute, | 3481 | __in HRESULT hrExecute, |
3433 | __in BOOL fRollback, | 3482 | __in BOOL fRollback, |
@@ -3445,7 +3494,7 @@ static HRESULT ExecutePackageComplete( | |||
3445 | { | 3494 | { |
3446 | *pRestart = BOOTSTRAPPER_APPLY_RESTART_INITIATED; | 3495 | *pRestart = BOOTSTRAPPER_APPLY_RESTART_INITIATED; |
3447 | } | 3496 | } |
3448 | *pfRetry = (FAILED(hrExecute) && BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_RETRY == executePackageCompleteAction); // allow retry only on failures. | 3497 | *pfRetry = (FAILED(hrExecute) && BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_RETRY == executePackageCompleteAction && !fAbandonedProcess); // allow retry only on failures. |
3449 | *pfSuspend = (BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_SUSPEND == executePackageCompleteAction); | 3498 | *pfSuspend = (BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_SUSPEND == executePackageCompleteAction); |
3450 | 3499 | ||
3451 | // Remember this package as the package that initiated the forced restart. | 3500 | // Remember this package as the package that initiated the forced restart. |
diff --git a/src/burn/engine/apply.h b/src/burn/engine/apply.h index 47f0ece6..7c786cc6 100644 --- a/src/burn/engine/apply.h +++ b/src/burn/engine/apply.h | |||
@@ -14,6 +14,8 @@ enum GENERIC_EXECUTE_MESSAGE_TYPE | |||
14 | GENERIC_EXECUTE_MESSAGE_PROGRESS, | 14 | GENERIC_EXECUTE_MESSAGE_PROGRESS, |
15 | GENERIC_EXECUTE_MESSAGE_NETFX_FILES_IN_USE, | 15 | GENERIC_EXECUTE_MESSAGE_NETFX_FILES_IN_USE, |
16 | GENERIC_EXECUTE_MESSAGE_PROCESS_CANCEL, | 16 | GENERIC_EXECUTE_MESSAGE_PROCESS_CANCEL, |
17 | GENERIC_EXECUTE_MESSAGE_PROCESS_STARTED, | ||
18 | GENERIC_EXECUTE_MESSAGE_PROCESS_COMPLETED, | ||
17 | }; | 19 | }; |
18 | 20 | ||
19 | typedef struct _APPLY_AUTHENTICATION_REQUIRED_DATA | 21 | typedef struct _APPLY_AUTHENTICATION_REQUIRED_DATA |
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp index 3c2872f1..ea56e242 100644 --- a/src/burn/engine/elevation.cpp +++ b/src/burn/engine/elevation.cpp | |||
@@ -44,6 +44,8 @@ typedef enum _BURN_ELEVATION_MESSAGE_TYPE | |||
44 | BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS, | 44 | BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS, |
45 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS, | 45 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS, |
46 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_CANCEL, | 46 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_CANCEL, |
47 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_STARTED, | ||
48 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_COMPLETED, | ||
47 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR, | 49 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR, |
48 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE, | 50 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE, |
49 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_FILES_IN_USE, | 51 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_FILES_IN_USE, |
@@ -1823,6 +1825,14 @@ static HRESULT ProcessGenericExecuteMessages( | |||
1823 | ExitOnFailure(hr, "Failed to read processId."); | 1825 | ExitOnFailure(hr, "Failed to read processId."); |
1824 | break; | 1826 | break; |
1825 | 1827 | ||
1828 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_STARTED: | ||
1829 | message.type = GENERIC_EXECUTE_MESSAGE_PROCESS_STARTED; | ||
1830 | break; | ||
1831 | |||
1832 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_COMPLETED: | ||
1833 | message.type = GENERIC_EXECUTE_MESSAGE_PROCESS_COMPLETED; | ||
1834 | break; | ||
1835 | |||
1826 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR: | 1836 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR: |
1827 | message.type = GENERIC_EXECUTE_MESSAGE_ERROR; | 1837 | message.type = GENERIC_EXECUTE_MESSAGE_ERROR; |
1828 | 1838 | ||
@@ -3465,6 +3475,14 @@ static int GenericExecuteMessageHandler( | |||
3465 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_CANCEL; | 3475 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_CANCEL; |
3466 | break; | 3476 | break; |
3467 | 3477 | ||
3478 | case GENERIC_EXECUTE_MESSAGE_PROCESS_STARTED: | ||
3479 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_STARTED; | ||
3480 | break; | ||
3481 | |||
3482 | case GENERIC_EXECUTE_MESSAGE_PROCESS_COMPLETED: | ||
3483 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_COMPLETED; | ||
3484 | break; | ||
3485 | |||
3468 | case GENERIC_EXECUTE_MESSAGE_ERROR: | 3486 | case GENERIC_EXECUTE_MESSAGE_ERROR: |
3469 | // serialize message data | 3487 | // serialize message data |
3470 | hr = BuffWriteNumber(&pbData, &cbData, pMessage->error.dwErrorCode); | 3488 | hr = BuffWriteNumber(&pbData, &cbData, pMessage->error.dwErrorCode); |
diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc index 9e139661..32473252 100644 --- a/src/burn/engine/engine.mc +++ b/src/burn/engine/engine.mc | |||
@@ -940,6 +940,13 @@ Language=English | |||
940 | Bootstrapper application requested delayed cancel during package process progress, id: %1!ls!. Waiting... | 940 | Bootstrapper application requested delayed cancel during package process progress, id: %1!ls!. Waiting... |
941 | . | 941 | . |
942 | 942 | ||
943 | MessageId=365 | ||
944 | Severity=Success | ||
945 | SymbolicName=MSG_APPLY_SKIPPED_PACKAGE_WITH_ABANDONED_PROCESS | ||
946 | Language=English | ||
947 | Skipping rollback of package: %1!ls! due to abandoning its process. Continuing... | ||
948 | . | ||
949 | |||
943 | MessageId=370 | 950 | MessageId=370 |
944 | Severity=Success | 951 | Severity=Success |
945 | SymbolicName=MSG_SESSION_BEGIN | 952 | SymbolicName=MSG_SESSION_BEGIN |
diff --git a/src/burn/engine/exeengine.cpp b/src/burn/engine/exeengine.cpp index 4c3c6fb0..a1049006 100644 --- a/src/burn/engine/exeengine.cpp +++ b/src/burn/engine/exeengine.cpp | |||
@@ -276,30 +276,33 @@ extern "C" HRESULT ExeEnginePlanAddPackage( | |||
276 | hr = DependencyPlanPackage(NULL, pPackage, pPlan); | 276 | hr = DependencyPlanPackage(NULL, pPackage, pPlan); |
277 | ExitOnFailure(hr, "Failed to plan package dependency actions."); | 277 | ExitOnFailure(hr, "Failed to plan package dependency actions."); |
278 | 278 | ||
279 | // add execute action | 279 | // add rollback action |
280 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute) | 280 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback) |
281 | { | 281 | { |
282 | hr = PlanAppendExecuteAction(pPlan, &pAction); | 282 | hr = PlanAppendRollbackAction(pPlan, &pAction); |
283 | ExitOnFailure(hr, "Failed to append execute action."); | 283 | ExitOnFailure(hr, "Failed to append rollback action."); |
284 | 284 | ||
285 | pAction->type = BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE; | 285 | pAction->type = BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE; |
286 | pAction->exePackage.pPackage = pPackage; | 286 | pAction->exePackage.pPackage = pPackage; |
287 | pAction->exePackage.action = pPackage->execute; | 287 | pAction->exePackage.action = pPackage->rollback; |
288 | 288 | ||
289 | LoggingSetPackageVariable(pPackage, NULL, FALSE, pLog, pVariables, NULL); // ignore errors. | 289 | LoggingSetPackageVariable(pPackage, NULL, TRUE, pLog, pVariables, NULL); // ignore errors. |
290 | |||
291 | hr = PlanExecuteCheckpoint(pPlan); | ||
292 | ExitOnFailure(hr, "Failed to append execute checkpoint."); | ||
290 | } | 293 | } |
291 | 294 | ||
292 | // add rollback action | 295 | // add execute action |
293 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback) | 296 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute) |
294 | { | 297 | { |
295 | hr = PlanAppendRollbackAction(pPlan, &pAction); | 298 | hr = PlanAppendExecuteAction(pPlan, &pAction); |
296 | ExitOnFailure(hr, "Failed to append rollback action."); | 299 | ExitOnFailure(hr, "Failed to append execute action."); |
297 | 300 | ||
298 | pAction->type = BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE; | 301 | pAction->type = BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE; |
299 | pAction->exePackage.pPackage = pPackage; | 302 | pAction->exePackage.pPackage = pPackage; |
300 | pAction->exePackage.action = pPackage->rollback; | 303 | pAction->exePackage.action = pPackage->execute; |
301 | 304 | ||
302 | LoggingSetPackageVariable(pPackage, NULL, TRUE, pLog, pVariables, NULL); // ignore errors. | 305 | LoggingSetPackageVariable(pPackage, NULL, FALSE, pLog, pVariables, NULL); // ignore errors. |
303 | } | 306 | } |
304 | 307 | ||
305 | LExit: | 308 | LExit: |
@@ -493,6 +496,10 @@ extern "C" HRESULT ExeEngineRunProcess( | |||
493 | ExitWithLastError(hr, "Failed to CreateProcess on path: %ls", wzExecutablePath); | 496 | ExitWithLastError(hr, "Failed to CreateProcess on path: %ls", wzExecutablePath); |
494 | } | 497 | } |
495 | 498 | ||
499 | message.type = GENERIC_EXECUTE_MESSAGE_PROCESS_STARTED; | ||
500 | message.dwUIHint = MB_OK; | ||
501 | pfnGenericMessageHandler(&message, pvContext); | ||
502 | |||
496 | if (fFireAndForget) | 503 | if (fFireAndForget) |
497 | { | 504 | { |
498 | ::WaitForInputIdle(pi.hProcess, 5000); | 505 | ::WaitForInputIdle(pi.hProcess, 5000); |
@@ -504,6 +511,7 @@ extern "C" HRESULT ExeEngineRunProcess( | |||
504 | // Wait for the executable process while sending fake progress to allow cancel. | 511 | // Wait for the executable process while sending fake progress to allow cancel. |
505 | do | 512 | do |
506 | { | 513 | { |
514 | memset(&message, 0, sizeof(message)); | ||
507 | message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; | 515 | message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; |
508 | message.dwUIHint = MB_OKCANCEL; | 516 | message.dwUIHint = MB_OKCANCEL; |
509 | message.progress.dwPercentage = 50; | 517 | message.progress.dwPercentage = 50; |
@@ -546,6 +554,11 @@ extern "C" HRESULT ExeEngineRunProcess( | |||
546 | } | 554 | } |
547 | } while (HRESULT_FROM_WIN32(WAIT_TIMEOUT) == hr); | 555 | } while (HRESULT_FROM_WIN32(WAIT_TIMEOUT) == hr); |
548 | 556 | ||
557 | memset(&message, 0, sizeof(message)); | ||
558 | message.type = GENERIC_EXECUTE_MESSAGE_PROCESS_COMPLETED; | ||
559 | message.dwUIHint = MB_OK; | ||
560 | pfnGenericMessageHandler(&message, pvContext); | ||
561 | |||
549 | if (fDelayedCancel) | 562 | if (fDelayedCancel) |
550 | { | 563 | { |
551 | ExitWithRootFailure(hr, HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT), "Bootstrapper application cancelled during package process progress, exit code: 0x%x", *pdwExitCode); | 564 | ExitWithRootFailure(hr, HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT), "Bootstrapper application cancelled during package process progress, exit code: 0x%x", *pdwExitCode); |
diff --git a/src/burn/engine/msuengine.cpp b/src/burn/engine/msuengine.cpp index 2f1fb61c..2591973f 100644 --- a/src/burn/engine/msuengine.cpp +++ b/src/burn/engine/msuengine.cpp | |||
@@ -222,30 +222,33 @@ extern "C" HRESULT MsuEnginePlanAddPackage( | |||
222 | hr = DependencyPlanPackage(NULL, pPackage, pPlan); | 222 | hr = DependencyPlanPackage(NULL, pPackage, pPlan); |
223 | ExitOnFailure(hr, "Failed to plan package dependency actions."); | 223 | ExitOnFailure(hr, "Failed to plan package dependency actions."); |
224 | 224 | ||
225 | // add execute action | 225 | // add rollback action |
226 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute) | 226 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback) |
227 | { | 227 | { |
228 | hr = PlanAppendExecuteAction(pPlan, &pAction); | 228 | hr = PlanAppendRollbackAction(pPlan, &pAction); |
229 | ExitOnFailure(hr, "Failed to append execute action."); | 229 | ExitOnFailure(hr, "Failed to append rollback action."); |
230 | 230 | ||
231 | pAction->type = BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE; | 231 | pAction->type = BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE; |
232 | pAction->msuPackage.pPackage = pPackage; | 232 | pAction->msuPackage.pPackage = pPackage; |
233 | pAction->msuPackage.action = pPackage->execute; | 233 | pAction->msuPackage.action = pPackage->rollback; |
234 | 234 | ||
235 | LoggingSetPackageVariable(pPackage, NULL, FALSE, pLog, pVariables, &pAction->msuPackage.sczLogPath); // ignore errors. | 235 | LoggingSetPackageVariable(pPackage, NULL, TRUE, pLog, pVariables, &pAction->msuPackage.sczLogPath); // ignore errors. |
236 | |||
237 | hr = PlanExecuteCheckpoint(pPlan); | ||
238 | ExitOnFailure(hr, "Failed to append execute checkpoint."); | ||
236 | } | 239 | } |
237 | 240 | ||
238 | // add rollback action | 241 | // add execute action |
239 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback) | 242 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute) |
240 | { | 243 | { |
241 | hr = PlanAppendRollbackAction(pPlan, &pAction); | 244 | hr = PlanAppendExecuteAction(pPlan, &pAction); |
242 | ExitOnFailure(hr, "Failed to append rollback action."); | 245 | ExitOnFailure(hr, "Failed to append execute action."); |
243 | 246 | ||
244 | pAction->type = BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE; | 247 | pAction->type = BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE; |
245 | pAction->msuPackage.pPackage = pPackage; | 248 | pAction->msuPackage.pPackage = pPackage; |
246 | pAction->msuPackage.action = pPackage->rollback; | 249 | pAction->msuPackage.action = pPackage->execute; |
247 | 250 | ||
248 | LoggingSetPackageVariable(pPackage, NULL, TRUE, pLog, pVariables, &pAction->msuPackage.sczLogPath); // ignore errors. | 251 | LoggingSetPackageVariable(pPackage, NULL, FALSE, pLog, pVariables, &pAction->msuPackage.sczLogPath); // ignore errors. |
249 | } | 252 | } |
250 | 253 | ||
251 | LExit: | 254 | LExit: |
diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h index eb40443d..e3e39c51 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h | |||
@@ -282,6 +282,7 @@ typedef struct _BURN_PACKAGE | |||
282 | LPWSTR sczCacheFolder; // only valid during Apply. | 282 | LPWSTR sczCacheFolder; // only valid during Apply. |
283 | HRESULT hrCacheResult; // only valid during Apply. | 283 | HRESULT hrCacheResult; // only valid during Apply. |
284 | BOOL fReachedExecution; // only valid during Apply. | 284 | BOOL fReachedExecution; // only valid during Apply. |
285 | BOOL fAbandonedProcess; // only valid during Apply. | ||
285 | 286 | ||
286 | BURN_PACKAGE_REGISTRATION_STATE cacheRegistrationState; // initialized during Detect, updated during Apply. | 287 | BURN_PACKAGE_REGISTRATION_STATE cacheRegistrationState; // initialized during Detect, updated during Apply. |
287 | BURN_PACKAGE_REGISTRATION_STATE installRegistrationState; // initialized during Detect, updated during Apply. | 288 | BURN_PACKAGE_REGISTRATION_STATE installRegistrationState; // initialized during Detect, updated during Apply. |
diff --git a/src/burn/test/BurnUnitTest/PlanTest.cpp b/src/burn/test/BurnUnitTest/PlanTest.cpp index 770922b4..2febe277 100644 --- a/src/burn/test/BurnUnitTest/PlanTest.cpp +++ b/src/burn/test/BurnUnitTest/PlanTest.cpp | |||
@@ -715,6 +715,7 @@ namespace Bootstrapper | |||
715 | ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); | 715 | ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); |
716 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 716 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
717 | ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"ExeA"); | 717 | ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"ExeA"); |
718 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
718 | ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"ExeA", BOOTSTRAPPER_ACTION_STATE_INSTALL); | 719 | ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"ExeA", BOOTSTRAPPER_ACTION_STATE_INSTALL); |
719 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 720 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
720 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 721 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
@@ -729,6 +730,7 @@ namespace Bootstrapper | |||
729 | ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"ExeA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL); | 730 | ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"ExeA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL); |
730 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 731 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
731 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 732 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
733 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
732 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); | 734 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); |
733 | Assert::Equal(dwIndex, pPlan->cRollbackActions); | 735 | Assert::Equal(dwIndex, pPlan->cRollbackActions); |
734 | 736 | ||
@@ -1682,6 +1684,7 @@ namespace Bootstrapper | |||
1682 | ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); | 1684 | ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); |
1683 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 1685 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
1684 | ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"test.msu"); | 1686 | ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"test.msu"); |
1687 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
1685 | ValidateExecuteMsuPackage(pPlan, fRollback, dwIndex++, L"test.msu", BOOTSTRAPPER_ACTION_STATE_INSTALL); | 1688 | ValidateExecuteMsuPackage(pPlan, fRollback, dwIndex++, L"test.msu", BOOTSTRAPPER_ACTION_STATE_INSTALL); |
1686 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 1689 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
1687 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 1690 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
@@ -1697,6 +1700,7 @@ namespace Bootstrapper | |||
1697 | ValidateExecuteMsuPackage(pPlan, fRollback, dwIndex++, L"test.msu", BOOTSTRAPPER_ACTION_STATE_UNINSTALL); | 1700 | ValidateExecuteMsuPackage(pPlan, fRollback, dwIndex++, L"test.msu", BOOTSTRAPPER_ACTION_STATE_UNINSTALL); |
1698 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 1701 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
1699 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 1702 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
1703 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
1700 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); | 1704 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); |
1701 | Assert::Equal(dwIndex, pPlan->cRollbackActions); | 1705 | Assert::Equal(dwIndex, pPlan->cRollbackActions); |
1702 | 1706 | ||
diff --git a/src/test/burn/TestBA/TestBA.cs b/src/test/burn/TestBA/TestBA.cs index c219ce9c..fdbcc6d4 100644 --- a/src/test/burn/TestBA/TestBA.cs +++ b/src/test/burn/TestBA/TestBA.cs | |||
@@ -4,6 +4,7 @@ namespace WixToolset.Test.BA | |||
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
7 | using System.Diagnostics; | ||
7 | using System.IO; | 8 | using System.IO; |
8 | using System.Linq; | 9 | using System.Linq; |
9 | using System.Threading; | 10 | using System.Threading; |
@@ -37,6 +38,7 @@ namespace WixToolset.Test.BA | |||
37 | private string cancelExecuteActionName; | 38 | private string cancelExecuteActionName; |
38 | private int cancelOnProgressAtProgress; | 39 | private int cancelOnProgressAtProgress; |
39 | private int retryExecuteFilesInUse; | 40 | private int retryExecuteFilesInUse; |
41 | private bool rollingBack; | ||
40 | 42 | ||
41 | private IBootstrapperCommand Command { get; } | 43 | private IBootstrapperCommand Command { get; } |
42 | 44 | ||
@@ -350,6 +352,8 @@ namespace WixToolset.Test.BA | |||
350 | { | 352 | { |
351 | this.Log("OnExecutePackageBegin() - package: {0}, rollback: {1}", args.PackageId, !args.ShouldExecute); | 353 | this.Log("OnExecutePackageBegin() - package: {0}, rollback: {1}", args.PackageId, !args.ShouldExecute); |
352 | 354 | ||
355 | this.rollingBack = !args.ShouldExecute; | ||
356 | |||
353 | string slowProgress = this.ReadPackageAction(args.PackageId, "SlowExecute"); | 357 | string slowProgress = this.ReadPackageAction(args.PackageId, "SlowExecute"); |
354 | if (String.IsNullOrEmpty(slowProgress) || !Int32.TryParse(slowProgress, out this.sleepDuringExecute)) | 358 | if (String.IsNullOrEmpty(slowProgress) || !Int32.TryParse(slowProgress, out this.sleepDuringExecute)) |
355 | { | 359 | { |
@@ -404,7 +408,7 @@ namespace WixToolset.Test.BA | |||
404 | if (!String.IsNullOrEmpty(recordTestRegistryValue) && Boolean.TryParse(recordTestRegistryValue, out logTestRegistryValue) && logTestRegistryValue) | 408 | if (!String.IsNullOrEmpty(recordTestRegistryValue) && Boolean.TryParse(recordTestRegistryValue, out logTestRegistryValue) && logTestRegistryValue) |
405 | { | 409 | { |
406 | var value = this.ReadTestRegistryValue(args.PackageId); | 410 | var value = this.ReadTestRegistryValue(args.PackageId); |
407 | this.Log("TestRegistryValue: {0}, Version, '{1}'", args.PackageId, value); | 411 | this.Log("TestRegistryValue: {0}, {1}, Version, '{2}'", this.rollingBack ? "Rollback" : "Execute", args.PackageId, value); |
408 | } | 412 | } |
409 | } | 413 | } |
410 | 414 | ||
@@ -419,8 +423,22 @@ namespace WixToolset.Test.BA | |||
419 | 423 | ||
420 | if (args.Action == BOOTSTRAPPER_EXECUTEPROCESSCANCEL_ACTION.Abandon) | 424 | if (args.Action == BOOTSTRAPPER_EXECUTEPROCESSCANCEL_ACTION.Abandon) |
421 | { | 425 | { |
422 | // Give time to the process to start before its files are deleted. | 426 | // Kill process to make sure it doesn't affect other tests. |
423 | Thread.Sleep(2000); | 427 | try |
428 | { | ||
429 | using (Process process = Process.GetProcessById(args.ProcessId)) | ||
430 | { | ||
431 | if (process != null) | ||
432 | { | ||
433 | process.Kill(); | ||
434 | } | ||
435 | } | ||
436 | } | ||
437 | catch (Exception e) | ||
438 | { | ||
439 | this.Log("Failed to kill process {0}: {1}", args.ProcessId, e); | ||
440 | Thread.Sleep(5000); | ||
441 | } | ||
424 | } | 442 | } |
425 | 443 | ||
426 | this.Log("OnExecuteProcessCancel({0})", args.Action); | 444 | this.Log("OnExecuteProcessCancel({0})", args.Action); |
@@ -494,6 +512,7 @@ namespace WixToolset.Test.BA | |||
494 | this.cancelOnProgressAtProgress = -1; | 512 | this.cancelOnProgressAtProgress = -1; |
495 | this.cancelExecuteAtProgress = -1; | 513 | this.cancelExecuteAtProgress = -1; |
496 | this.cancelCacheAtProgress = -1; | 514 | this.cancelCacheAtProgress = -1; |
515 | this.rollingBack = false; | ||
497 | } | 516 | } |
498 | 517 | ||
499 | protected override void OnApplyComplete(ApplyCompleteEventArgs args) | 518 | protected override void OnApplyComplete(ApplyCompleteEventArgs args) |
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs index bbc0b387..b50be49a 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs | |||
@@ -25,12 +25,8 @@ namespace WixToolsetTest.BurnE2E | |||
25 | var logPath = bundleD.Install((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_USEREXIT); | 25 | var logPath = bundleD.Install((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_USEREXIT); |
26 | bundleD.VerifyUnregisteredAndRemovedFromPackageCache(); | 26 | bundleD.VerifyUnregisteredAndRemovedFromPackageCache(); |
27 | 27 | ||
28 | Assert.True(LogVerifier.MessageInLogFile(logPath, "TestRegistryValue: ExeA, Version, ''")); | 28 | Assert.True(LogVerifier.MessageInLogFile(logPath, "TestRegistryValue: Execute, ExeA, Version, ''")); |
29 | 29 | Assert.False(LogVerifier.MessageInLogFile(logPath, "TestRegistryValue: Rollback, ExeA, Version")); | |
30 | // Make sure ExeA finishes running. | ||
31 | Thread.Sleep(3000); | ||
32 | |||
33 | bundleD.VerifyExeTestRegistryValue("ExeA", "1.0.0.0"); | ||
34 | } | 30 | } |
35 | 31 | ||
36 | [Fact] | 32 | [Fact] |
@@ -47,9 +43,11 @@ namespace WixToolsetTest.BurnE2E | |||
47 | var logPath = bundleD.Install((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_USEREXIT); | 43 | var logPath = bundleD.Install((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_USEREXIT); |
48 | bundleD.VerifyUnregisteredAndRemovedFromPackageCache(); | 44 | bundleD.VerifyUnregisteredAndRemovedFromPackageCache(); |
49 | 45 | ||
50 | Assert.True(LogVerifier.MessageInLogFile(logPath, "TestRegistryValue: ExeA, Version, '1.0.0.0'")); | 46 | Assert.True(LogVerifier.MessageInLogFile(logPath, "TestRegistryValue: Execute, ExeA, Version, '1.0.0.0'")); |
47 | Assert.True(LogVerifier.MessageInLogFile(logPath, "TestRegistryValue: Rollback, ExeA, Version, ''")); | ||
51 | 48 | ||
52 | bundleD.VerifyExeTestRegistryValue("ExeA", "1.0.0.0"); | 49 | // The package should have rolled back. |
50 | bundleD.VerifyExeTestRegistryRootDeleted("ExeA"); | ||
53 | } | 51 | } |
54 | 52 | ||
55 | [Fact] | 53 | [Fact] |