diff options
| author | Bob Arnson <bob@firegiant.com> | 2022-07-23 00:03:58 -0400 |
|---|---|---|
| committer | Bob Arnson <github@bobs.org> | 2022-07-25 13:04:12 -0400 |
| commit | f1c74f3f60a0b1845806a2c6f7082692a8f37b7e (patch) | |
| tree | d833dcd9b81a740a8a7124b0271ba953aa6ea411 | |
| parent | 339fc1d2148e6b7fe8cd664e81ee65e51405aa23 (diff) | |
| download | wix-f1c74f3f60a0b1845806a2c6f7082692a8f37b7e.tar.gz wix-f1c74f3f60a0b1845806a2c6f7082692a8f37b7e.tar.bz2 wix-f1c74f3f60a0b1845806a2c6f7082692a8f37b7e.zip | |
Add files-in-use task dialog.
Remove ErrorFailNoActionReboot loc string, now that XP is dead (RIP).
Clean up some extra stuff, because I'm all up in the code.
Resolves https://github.com/wixtoolset/issues/issues/6545.
Diffstat (limited to '')
| -rw-r--r-- | src/clean.cmd | 3 | ||||
| -rw-r--r-- | src/ext/Bal/wixstdba/Resources/HyperlinkTheme.wxl | 5 | ||||
| -rw-r--r-- | src/ext/Bal/wixstdba/Resources/RtfTheme.wxl | 5 | ||||
| -rw-r--r-- | src/ext/Bal/wixstdba/Resources/dncpreq.wxl | 1 | ||||
| -rw-r--r-- | src/ext/Bal/wixstdba/Resources/mbapreq.wxl | 1 | ||||
| -rw-r--r-- | src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp | 174 | ||||
| -rw-r--r-- | src/test/burn/TestData/FilesInUseTests/WixStdBaBundle/WixStdBaBundle.wixproj | 17 | ||||
| -rw-r--r-- | src/test/burn/TestData/FilesInUseTests/WixStdBaBundle/WixStdBaBundle.wxs | 10 | ||||
| -rw-r--r-- | src/test/burn/WixToolsetTest.BurnE2E/FilesInUseTests.cs | 20 | ||||
| -rw-r--r-- | src/tools/thmviewer/precomp.h | 2 |
10 files changed, 214 insertions, 24 deletions
diff --git a/src/clean.cmd b/src/clean.cmd index bd44bed4..9c4fa0dc 100644 --- a/src/clean.cmd +++ b/src/clean.cmd | |||
| @@ -2,7 +2,10 @@ | |||
| 2 | 2 | ||
| 3 | setlocal | 3 | setlocal |
| 4 | pushd %~dp0 | 4 | pushd %~dp0 |
| 5 | |||
| 5 | set _NUGET_CACHE=%USERPROFILE%\.nuget\packages | 6 | set _NUGET_CACHE=%USERPROFILE%\.nuget\packages |
| 7 | if "%NUGET_PACKAGES%" NEQ "" set _NUGET_CACHE=%NUGET_PACKAGES% | ||
| 8 | |||
| 6 | echo Cleaning... | 9 | echo Cleaning... |
| 7 | 10 | ||
| 8 | if exist ..\build rd /s/q ..\build | 11 | if exist ..\build rd /s/q ..\build |
diff --git a/src/ext/Bal/wixstdba/Resources/HyperlinkTheme.wxl b/src/ext/Bal/wixstdba/Resources/HyperlinkTheme.wxl index 43b43970..9fd0be43 100644 --- a/src/ext/Bal/wixstdba/Resources/HyperlinkTheme.wxl +++ b/src/ext/Bal/wixstdba/Resources/HyperlinkTheme.wxl | |||
| @@ -63,5 +63,8 @@ | |||
| 63 | <String Id="FailureRestartText">You must restart your computer to complete the rollback of the software.</String> | 63 | <String Id="FailureRestartText">You must restart your computer to complete the rollback of the software.</String> |
| 64 | <String Id="FailureRestartButton">&Restart</String> | 64 | <String Id="FailureRestartButton">&Restart</String> |
| 65 | <String Id="FailureCloseButton">&Close</String> | 65 | <String Id="FailureCloseButton">&Close</String> |
| 66 | <String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String> | 66 | <String Id="FilesInUseTitle">Files In Use</String> |
| 67 | <String Id="FilesInUseLabel">The following applications are using files that need to be updated:</String> | ||
| 68 | <String Id="FilesInUseCloseRadioButton">Close the &applications and attempt to restart them.</String> | ||
| 69 | <String Id="FilesInUseDontCloseRadioButton">&Do not close applications. A reboot will be required.</String> | ||
| 67 | </WixLocalization> | 70 | </WixLocalization> |
diff --git a/src/ext/Bal/wixstdba/Resources/RtfTheme.wxl b/src/ext/Bal/wixstdba/Resources/RtfTheme.wxl index 7b8e1c65..4948cd75 100644 --- a/src/ext/Bal/wixstdba/Resources/RtfTheme.wxl +++ b/src/ext/Bal/wixstdba/Resources/RtfTheme.wxl | |||
| @@ -60,5 +60,8 @@ | |||
| 60 | <String Id="FailureRestartText">You must restart your computer to complete the rollback of the software.</String> | 60 | <String Id="FailureRestartText">You must restart your computer to complete the rollback of the software.</String> |
| 61 | <String Id="FailureRestartButton">&Restart</String> | 61 | <String Id="FailureRestartButton">&Restart</String> |
| 62 | <String Id="FailureCloseButton">&Close</String> | 62 | <String Id="FailureCloseButton">&Close</String> |
| 63 | <String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String> | 63 | <String Id="FilesInUseTitle">Files In Use</String> |
| 64 | <String Id="FilesInUseLabel">The following applications are using files that need to be updated:</String> | ||
| 65 | <String Id="FilesInUseCloseRadioButton">Close the &applications and attempt to restart them.</String> | ||
| 66 | <String Id="FilesInUseDontCloseRadioButton">&Do not close applications. A reboot will be required.</String> | ||
| 64 | </WixLocalization> | 67 | </WixLocalization> |
diff --git a/src/ext/Bal/wixstdba/Resources/dncpreq.wxl b/src/ext/Bal/wixstdba/Resources/dncpreq.wxl index 22fcd3dc..734de0ed 100644 --- a/src/ext/Bal/wixstdba/Resources/dncpreq.wxl +++ b/src/ext/Bal/wixstdba/Resources/dncpreq.wxl | |||
| @@ -30,5 +30,4 @@ | |||
| 30 | <String Id="FailureCloseButton">&Close</String> | 30 | <String Id="FailureCloseButton">&Close</String> |
| 31 | <String Id="SCDRUNTIMEFAILUREErrorMessage">[WixBundleName] cannot run on this machine. Install the latest updates and/or the latest OS to run in a supported environment.</String> | 31 | <String Id="SCDRUNTIMEFAILUREErrorMessage">[WixBundleName] cannot run on this machine. Install the latest updates and/or the latest OS to run in a supported environment.</String> |
| 32 | <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Core runtime even though all of the prerequisites are installed.</String> | 32 | <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Core runtime even though all of the prerequisites are installed.</String> |
| 33 | <String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String> | ||
| 34 | </WixLocalization> | 33 | </WixLocalization> |
diff --git a/src/ext/Bal/wixstdba/Resources/mbapreq.wxl b/src/ext/Bal/wixstdba/Resources/mbapreq.wxl index 77859d31..3fec4254 100644 --- a/src/ext/Bal/wixstdba/Resources/mbapreq.wxl +++ b/src/ext/Bal/wixstdba/Resources/mbapreq.wxl | |||
| @@ -30,5 +30,4 @@ | |||
| 30 | <String Id="FailureCloseButton">&Close</String> | 30 | <String Id="FailureCloseButton">&Close</String> |
| 31 | <String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String> | 31 | <String Id="NET452WIN7RTMErrorMessage">[WixBundleName] cannot run on Windows 7 RTM with .NET 4.5.2 installed. Install Windows 7 SP1 to run in a supported environment.</String> |
| 32 | <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String> | 32 | <String Id="PREREQBAINFINITELOOPErrorMessage">[WixBundleName] failed to load the .NET Framework runtime even though all of the prerequisites are installed.</String> |
| 33 | <String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String> | ||
| 34 | </WixLocalization> | 33 | </WixLocalization> |
diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp index 1af1abeb..bd0f5a3b 100644 --- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp +++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp | |||
| @@ -867,25 +867,9 @@ public: // IBootstrapperApplication | |||
| 867 | hr = StrAllocFromError(&sczError, dwCode, NULL); | 867 | hr = StrAllocFromError(&sczError, dwCode, NULL); |
| 868 | if (FAILED(hr) || !sczError || !*sczError) | 868 | if (FAILED(hr) || !sczError || !*sczError) |
| 869 | { | 869 | { |
| 870 | // special case for ERROR_FAIL_NOACTION_REBOOT: use loc string for Windows XP | 870 | StrAllocFormatted(&sczError, L"0x%x", dwCode); |
| 871 | if (ERROR_FAIL_NOACTION_REBOOT == dwCode) | ||
| 872 | { | ||
| 873 | LOC_STRING* pLocString = NULL; | ||
| 874 | hr = LocGetString(m_pWixLoc, L"#(loc.ErrorFailNoActionReboot)", &pLocString); | ||
| 875 | if (SUCCEEDED(hr)) | ||
| 876 | { | ||
| 877 | StrAllocString(&sczError, pLocString->wzText, 0); | ||
| 878 | } | ||
| 879 | else | ||
| 880 | { | ||
| 881 | StrAllocFormatted(&sczError, L"0x%x", dwCode); | ||
| 882 | } | ||
| 883 | } | ||
| 884 | else | ||
| 885 | { | ||
| 886 | StrAllocFormatted(&sczError, L"0x%x", dwCode); | ||
| 887 | } | ||
| 888 | } | 871 | } |
| 872 | |||
| 889 | hr = S_OK; | 873 | hr = S_OK; |
| 890 | } | 874 | } |
| 891 | 875 | ||
| @@ -1053,6 +1037,34 @@ public: // IBootstrapperApplication | |||
| 1053 | } | 1037 | } |
| 1054 | 1038 | ||
| 1055 | 1039 | ||
| 1040 | virtual STDMETHODIMP OnExecuteFilesInUse( | ||
| 1041 | __in_z LPCWSTR wzPackageId, | ||
| 1042 | __in DWORD cFiles, | ||
| 1043 | __in_ecount_z(cFiles) LPCWSTR* rgwzFiles, | ||
| 1044 | __in int nRecommendation, | ||
| 1045 | __in BOOTSTRAPPER_FILES_IN_USE_TYPE source, | ||
| 1046 | __inout int* pResult | ||
| 1047 | ) | ||
| 1048 | { | ||
| 1049 | |||
| 1050 | if (!m_fShowingInternalUiThisPackage && !m_fPrereq && wzPackageId && *wzPackageId) | ||
| 1051 | { | ||
| 1052 | // If this is an MSI package, display the files-in-use dialog. | ||
| 1053 | BAL_INFO_PACKAGE* pPackage = NULL; | ||
| 1054 | BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage); | ||
| 1055 | |||
| 1056 | if (pPackage && BAL_INFO_PACKAGE_TYPE_MSI == pPackage->type) | ||
| 1057 | { | ||
| 1058 | BalLog(BOOTSTRAPPER_LOG_LEVEL_VERBOSE, "Package %ls has %d applications holding files in use.", wzPackageId, cFiles); | ||
| 1059 | |||
| 1060 | return ShowFilesInUse(cFiles, rgwzFiles, source); | ||
| 1061 | } | ||
| 1062 | } | ||
| 1063 | |||
| 1064 | return __super::OnExecuteFilesInUse(wzPackageId, cFiles, rgwzFiles, nRecommendation, source, pResult); | ||
| 1065 | } | ||
| 1066 | |||
| 1067 | |||
| 1056 | virtual STDMETHODIMP OnExecutePackageComplete( | 1068 | virtual STDMETHODIMP OnExecutePackageComplete( |
| 1057 | __in_z LPCWSTR wzPackageId, | 1069 | __in_z LPCWSTR wzPackageId, |
| 1058 | __in HRESULT hrStatus, | 1070 | __in HRESULT hrStatus, |
| @@ -2201,6 +2213,126 @@ private: // privates | |||
| 2201 | } | 2213 | } |
| 2202 | 2214 | ||
| 2203 | 2215 | ||
| 2216 | int ShowFilesInUse( | ||
| 2217 | __in DWORD cFiles, | ||
| 2218 | __in_ecount_z(cFiles) LPCWSTR* rgwzFiles, | ||
| 2219 | __in BOOTSTRAPPER_FILES_IN_USE_TYPE /*source*/ | ||
| 2220 | ) | ||
| 2221 | { | ||
| 2222 | HRESULT hr = S_OK; | ||
| 2223 | LPWSTR sczFilesInUse = NULL; | ||
| 2224 | DWORD_PTR cchLen = 0; | ||
| 2225 | int nResult = IDERROR; | ||
| 2226 | |||
| 2227 | // If the user has choosen to ignore on a previously displayed "files in use" page, | ||
| 2228 | // we will return the same result for other cases. No need to display the page again. | ||
| 2229 | if (IDIGNORE == m_nLastFilesInUseResult) | ||
| 2230 | { | ||
| 2231 | nResult = m_nLastFilesInUseResult; | ||
| 2232 | } | ||
| 2233 | else if (BOOTSTRAPPER_DISPLAY_FULL == m_command.display) // Only show files in use when using full display mode. | ||
| 2234 | { | ||
| 2235 | // Show applications using the files. | ||
| 2236 | if (cFiles > 0) | ||
| 2237 | { | ||
| 2238 | // See https://msdn.microsoft.com/en-us/library/aa371614%28v=vs.85%29.aspx for details. | ||
| 2239 | for (DWORD i = 1; i < cFiles; i += 2) | ||
| 2240 | { | ||
| 2241 | hr = ::StringCchLengthW(rgwzFiles[i], STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchLen)); | ||
| 2242 | BalExitOnFailure(hr, "Failed to calculate length of string"); | ||
| 2243 | |||
| 2244 | if (cchLen > 0) | ||
| 2245 | { | ||
| 2246 | hr = StrAllocConcat(&sczFilesInUse, rgwzFiles[i], 0); | ||
| 2247 | BalExitOnFailure(hr, "Failed to concat files in use"); | ||
| 2248 | |||
| 2249 | hr = StrAllocConcat(&sczFilesInUse, L"\r\n", 2); | ||
| 2250 | BalExitOnFailure(hr, "Failed to concat files in use"); | ||
| 2251 | } | ||
| 2252 | } | ||
| 2253 | } | ||
| 2254 | |||
| 2255 | hr = ShowFilesInUseDialog(sczFilesInUse, &nResult); | ||
| 2256 | ExitOnFailure(hr, "Failed to show files-in-use task dialog."); | ||
| 2257 | } | ||
| 2258 | else | ||
| 2259 | { | ||
| 2260 | // Silent UI level installations always shut down applications and services, | ||
| 2261 | // and on Windows Vista and later, use Restart Manager unless disabled. | ||
| 2262 | nResult = IDOK; | ||
| 2263 | } | ||
| 2264 | |||
| 2265 | LExit: | ||
| 2266 | ReleaseStr(sczFilesInUse); | ||
| 2267 | |||
| 2268 | // Remember the answer from the user. | ||
| 2269 | m_nLastFilesInUseResult = FAILED(hr) ? IDERROR : nResult; | ||
| 2270 | |||
| 2271 | return m_nLastFilesInUseResult; | ||
| 2272 | } | ||
| 2273 | |||
| 2274 | |||
| 2275 | int ShowFilesInUseDialog( | ||
| 2276 | __in_z_opt LPCWSTR sczFilesInUse, | ||
| 2277 | __out int* pnResult | ||
| 2278 | ) | ||
| 2279 | { | ||
| 2280 | HRESULT hr = S_OK; | ||
| 2281 | TASKDIALOGCONFIG config = { }; | ||
| 2282 | LPWSTR sczTitle = NULL; | ||
| 2283 | LPWSTR sczLabel = NULL; | ||
| 2284 | LPWSTR sczCloseRadioButton = NULL; | ||
| 2285 | LPWSTR sczDontCloseRadioButton = NULL; | ||
| 2286 | LOC_STRING* pLocString = NULL; | ||
| 2287 | |||
| 2288 | // Get the loc strings for the files-in-use task dialog text. | ||
| 2289 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseTitle)", &pLocString); | ||
| 2290 | ExitOnFailure(hr, "Failed to get FilesInUseTitle loc string."); | ||
| 2291 | |||
| 2292 | hr = StrAllocString(&sczTitle, pLocString->wzText, 0); | ||
| 2293 | ExitOnFailure(hr, "Failed to copy FilesInUseTitle loc string."); | ||
| 2294 | |||
| 2295 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseLabel)", &pLocString); | ||
| 2296 | ExitOnFailure(hr, "Failed to get FilesInUseLabel loc string."); | ||
| 2297 | |||
| 2298 | hr = StrAllocString(&sczLabel, pLocString->wzText, 0); | ||
| 2299 | ExitOnFailure(hr, "Failed to copy FilesInUseLabel loc string."); | ||
| 2300 | |||
| 2301 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseCloseRadioButton)", &pLocString); | ||
| 2302 | ExitOnFailure(hr, "Failed to get FilesInUseCloseRadioButton loc string."); | ||
| 2303 | |||
| 2304 | hr = StrAllocString(&sczCloseRadioButton, pLocString->wzText, 0); | ||
| 2305 | ExitOnFailure(hr, "Failed to copy FilesInUseCloseRadioButton loc string."); | ||
| 2306 | |||
| 2307 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseDontCloseRadioButton)", &pLocString); | ||
| 2308 | ExitOnFailure(hr, "Failed to get FilesInUseDontCloseRadioButton loc string."); | ||
| 2309 | |||
| 2310 | hr = StrAllocString(&sczDontCloseRadioButton, pLocString->wzText, 0); | ||
| 2311 | ExitOnFailure(hr, "Failed to copy FilesInUseDontCloseRadioButton loc string."); | ||
| 2312 | |||
| 2313 | const TASKDIALOG_BUTTON buttons[] = { | ||
| 2314 | { IDOK, sczCloseRadioButton }, | ||
| 2315 | { IDIGNORE, sczDontCloseRadioButton }, | ||
| 2316 | }; | ||
| 2317 | |||
| 2318 | config.cbSize = sizeof(config); | ||
| 2319 | config.hInstance = m_hModule; | ||
| 2320 | config.dwFlags = TDF_ALLOW_DIALOG_CANCELLATION | TDF_USE_COMMAND_LINKS | TDF_SIZE_TO_CONTENT; | ||
| 2321 | config.dwCommonButtons = TDCBF_CANCEL_BUTTON; | ||
| 2322 | config.pszWindowTitle = sczTitle; | ||
| 2323 | config.pszMainInstruction = sczLabel; | ||
| 2324 | config.pszContent = sczFilesInUse ? sczFilesInUse : L""; | ||
| 2325 | config.pButtons = buttons; | ||
| 2326 | config.cButtons = 2; | ||
| 2327 | |||
| 2328 | hr = TaskDialogIndirect(&config, pnResult, NULL, NULL); | ||
| 2329 | ExitOnFailure(hr, "Failed to show files-in-use task dialog."); | ||
| 2330 | |||
| 2331 | LExit: | ||
| 2332 | return hr; | ||
| 2333 | } | ||
| 2334 | |||
| 2335 | |||
| 2204 | public: //CBalBaseBootstrapperApplication | 2336 | public: //CBalBaseBootstrapperApplication |
| 2205 | virtual STDMETHODIMP Initialize( | 2337 | virtual STDMETHODIMP Initialize( |
| 2206 | __in const BOOTSTRAPPER_CREATE_ARGS* pCreateArgs | 2338 | __in const BOOTSTRAPPER_CREATE_ARGS* pCreateArgs |
| @@ -4135,7 +4267,7 @@ LExit: | |||
| 4135 | if (m_fTaskbarButtonOK) | 4267 | if (m_fTaskbarButtonOK) |
| 4136 | { | 4268 | { |
| 4137 | hr = m_pTaskbarList->SetProgressState(m_hWnd, tbpFlags); | 4269 | hr = m_pTaskbarList->SetProgressState(m_hWnd, tbpFlags); |
| 4138 | BalExitOnFailure(hr, "Failed to set taskbar button state.", tbpFlags); | 4270 | BalExitOnFailure(hr, "Failed to set taskbar button state: %d.", tbpFlags); |
| 4139 | } | 4271 | } |
| 4140 | 4272 | ||
| 4141 | LExit: | 4273 | LExit: |
| @@ -4286,6 +4418,8 @@ public: | |||
| 4286 | m_fPrereqInstalled = FALSE; | 4418 | m_fPrereqInstalled = FALSE; |
| 4287 | m_fPrereqSkipped = FALSE; | 4419 | m_fPrereqSkipped = FALSE; |
| 4288 | 4420 | ||
| 4421 | m_nLastFilesInUseResult = IDNOACTION; | ||
| 4422 | |||
| 4289 | pEngine->AddRef(); | 4423 | pEngine->AddRef(); |
| 4290 | m_pEngine = pEngine; | 4424 | m_pEngine = pEngine; |
| 4291 | 4425 | ||
| @@ -4578,6 +4712,8 @@ private: | |||
| 4578 | BOOL m_fShowingInternalUiThisPackage; | 4712 | BOOL m_fShowingInternalUiThisPackage; |
| 4579 | BOOL m_fTriedToLaunchElevated; | 4713 | BOOL m_fTriedToLaunchElevated; |
| 4580 | 4714 | ||
| 4715 | int m_nLastFilesInUseResult; | ||
| 4716 | |||
| 4581 | HMODULE m_hBAFModule; | 4717 | HMODULE m_hBAFModule; |
| 4582 | PFN_BA_FUNCTIONS_PROC m_pfnBAFunctionsProc; | 4718 | PFN_BA_FUNCTIONS_PROC m_pfnBAFunctionsProc; |
| 4583 | LPVOID m_pvBAFunctionsProcContext; | 4719 | LPVOID m_pvBAFunctionsProcContext; |
diff --git a/src/test/burn/TestData/FilesInUseTests/WixStdBaBundle/WixStdBaBundle.wixproj b/src/test/burn/TestData/FilesInUseTests/WixStdBaBundle/WixStdBaBundle.wixproj new file mode 100644 index 00000000..e0860665 --- /dev/null +++ b/src/test/burn/TestData/FilesInUseTests/WixStdBaBundle/WixStdBaBundle.wixproj | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 2 | <Project Sdk="WixToolset.Sdk"> | ||
| 3 | <PropertyGroup> | ||
| 4 | <OutputType>Bundle</OutputType> | ||
| 5 | <UpgradeCode>{6A348108-8ACE-4D13-A352-D8F76785BFE4}</UpgradeCode> | ||
| 6 | <DefineConstants>$(DefineConstants);BaseOutputPath=$(BaseOutputPath);Version=1.1</DefineConstants> | ||
| 7 | </PropertyGroup> | ||
| 8 | <ItemGroup> | ||
| 9 | <Compile Include="..\..\WixStdBaTests\BundleA\Bundle.wxs" Link="Bundle.wxs" /> | ||
| 10 | </ItemGroup> | ||
| 11 | <ItemGroup> | ||
| 12 | <ProjectReference Include="..\PackageA\PackageA.wixproj" /> | ||
| 13 | </ItemGroup> | ||
| 14 | <ItemGroup> | ||
| 15 | <PackageReference Include="WixToolset.Bal.wixext" /> | ||
| 16 | </ItemGroup> | ||
| 17 | </Project> \ No newline at end of file | ||
diff --git a/src/test/burn/TestData/FilesInUseTests/WixStdBaBundle/WixStdBaBundle.wxs b/src/test/burn/TestData/FilesInUseTests/WixStdBaBundle/WixStdBaBundle.wxs new file mode 100644 index 00000000..bd164a29 --- /dev/null +++ b/src/test/burn/TestData/FilesInUseTests/WixStdBaBundle/WixStdBaBundle.wxs | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 2 | |||
| 3 | |||
| 4 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | ||
| 5 | <Fragment> | ||
| 6 | <PackageGroup Id="BundlePackages"> | ||
| 7 | <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" /> | ||
| 8 | </PackageGroup> | ||
| 9 | </Fragment> | ||
| 10 | </Wix> | ||
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/FilesInUseTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/FilesInUseTests.cs index 042175f0..12eca77d 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/FilesInUseTests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/FilesInUseTests.cs | |||
| @@ -33,5 +33,25 @@ namespace WixToolsetTest.BurnE2E | |||
| 33 | 33 | ||
| 34 | packageA.VerifyInstalled(false); | 34 | packageA.VerifyInstalled(false); |
| 35 | } | 35 | } |
| 36 | |||
| 37 | [RuntimeFact] | ||
| 38 | public void WixStdBAFailsWithLockedFile() | ||
| 39 | { | ||
| 40 | var packageA = this.CreatePackageInstaller("PackageA"); | ||
| 41 | var bundleA = this.CreateBundleInstaller("WixStdBaBundle"); | ||
| 42 | |||
| 43 | packageA.VerifyInstalled(false); | ||
| 44 | |||
| 45 | bundleA.Install(); | ||
| 46 | |||
| 47 | packageA.VerifyInstalled(true); | ||
| 48 | |||
| 49 | // Lock the file that will be uninstalled. | ||
| 50 | var targetInstallFile = packageA.GetInstalledFilePath("Package.wxs"); | ||
| 51 | using (var lockTargetFile = new FileStream(targetInstallFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) | ||
| 52 | { | ||
| 53 | bundleA.Uninstall(expectedExitCode: (int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_FAILURE); | ||
| 54 | } | ||
| 55 | } | ||
| 36 | } | 56 | } |
| 37 | } | 57 | } |
diff --git a/src/tools/thmviewer/precomp.h b/src/tools/thmviewer/precomp.h index 762a0623..41d2e9fb 100644 --- a/src/tools/thmviewer/precomp.h +++ b/src/tools/thmviewer/precomp.h | |||
| @@ -55,7 +55,7 @@ extern "C" HRESULT DisplayStart( | |||
| 55 | ); | 55 | ); |
| 56 | extern "C" HRESULT LoadStart( | 56 | extern "C" HRESULT LoadStart( |
| 57 | __in_z LPCWSTR wzThemePath, | 57 | __in_z LPCWSTR wzThemePath, |
| 58 | __in_z LPCWSTR wzWxlPath, | 58 | __in_z_opt LPCWSTR wzWxlPath, |
| 59 | __in HWND hWnd, | 59 | __in HWND hWnd, |
| 60 | __out HANDLE* phThread | 60 | __out HANDLE* phThread |
| 61 | ); | 61 | ); |
