diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2022-07-24 14:09:53 -0500 |
|---|---|---|
| committer | Bob Arnson <github@bobs.org> | 2022-07-25 13:04:12 -0400 |
| commit | b86beafe859dea600209d19502bc194affd5fe2b (patch) | |
| tree | 4eaeeb3cfb51f06119b21a9990daa530571e24da /src | |
| parent | 2e327df0b7c785a6cad36f6b3bf79ba8becf9000 (diff) | |
| download | wix-b86beafe859dea600209d19502bc194affd5fe2b.tar.gz wix-b86beafe859dea600209d19502bc194affd5fe2b.tar.bz2 wix-b86beafe859dea600209d19502bc194affd5fe2b.zip | |
Add dialog for non-RM FilesInUse and Netfx FilesInUse.
Fixes 5208
Diffstat (limited to '')
| -rw-r--r-- | src/ext/Bal/wixstdba/Resources/HyperlinkTheme.wxl | 4 | ||||
| -rw-r--r-- | src/ext/Bal/wixstdba/Resources/RtfTheme.wxl | 4 | ||||
| -rw-r--r-- | src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp | 266 |
3 files changed, 246 insertions, 28 deletions
diff --git a/src/ext/Bal/wixstdba/Resources/HyperlinkTheme.wxl b/src/ext/Bal/wixstdba/Resources/HyperlinkTheme.wxl index 9fd0be43..cb1f8da4 100644 --- a/src/ext/Bal/wixstdba/Resources/HyperlinkTheme.wxl +++ b/src/ext/Bal/wixstdba/Resources/HyperlinkTheme.wxl | |||
| @@ -65,6 +65,10 @@ | |||
| 65 | <String Id="FailureCloseButton">&Close</String> | 65 | <String Id="FailureCloseButton">&Close</String> |
| 66 | <String Id="FilesInUseTitle">Files In Use</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> | 67 | <String Id="FilesInUseLabel">The following applications are using files that need to be updated:</String> |
| 68 | <String Id="FilesInUseNetfxCloseRadioButton">Close the &applications.</String> | ||
| 68 | <String Id="FilesInUseCloseRadioButton">Close the &applications and attempt to restart them.</String> | 69 | <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> | 70 | <String Id="FilesInUseDontCloseRadioButton">&Do not close applications. A reboot will be required.</String> |
| 71 | <String Id="FilesInUseRetryButton">&Retry</String> | ||
| 72 | <String Id="FilesInUseIgnoreButton">&Ignore</String> | ||
| 73 | <String Id="FilesInUseExitButton">E&xit</String> | ||
| 70 | </WixLocalization> | 74 | </WixLocalization> |
diff --git a/src/ext/Bal/wixstdba/Resources/RtfTheme.wxl b/src/ext/Bal/wixstdba/Resources/RtfTheme.wxl index 4948cd75..efe66f41 100644 --- a/src/ext/Bal/wixstdba/Resources/RtfTheme.wxl +++ b/src/ext/Bal/wixstdba/Resources/RtfTheme.wxl | |||
| @@ -62,6 +62,10 @@ | |||
| 62 | <String Id="FailureCloseButton">&Close</String> | 62 | <String Id="FailureCloseButton">&Close</String> |
| 63 | <String Id="FilesInUseTitle">Files In Use</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> | 64 | <String Id="FilesInUseLabel">The following applications are using files that need to be updated:</String> |
| 65 | <String Id="FilesInUseNetfxCloseRadioButton">Close the &applications.</String> | ||
| 65 | <String Id="FilesInUseCloseRadioButton">Close the &applications and attempt to restart them.</String> | 66 | <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> | 67 | <String Id="FilesInUseDontCloseRadioButton">&Do not close applications. A reboot will be required.</String> |
| 68 | <String Id="FilesInUseRetryButton">&Retry</String> | ||
| 69 | <String Id="FilesInUseIgnoreButton">&Ignore</String> | ||
| 70 | <String Id="FilesInUseExitButton">E&xit</String> | ||
| 67 | </WixLocalization> | 71 | </WixLocalization> |
diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp index 2ef829d7..5fc20368 100644 --- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp +++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp | |||
| @@ -604,6 +604,8 @@ public: // IBootstrapperApplication | |||
| 604 | m_fStartedExecution = FALSE; | 604 | m_fStartedExecution = FALSE; |
| 605 | m_dwCalculatedCacheProgress = 0; | 605 | m_dwCalculatedCacheProgress = 0; |
| 606 | m_dwCalculatedExecuteProgress = 0; | 606 | m_dwCalculatedExecuteProgress = 0; |
| 607 | m_nLastMsiFilesInUseResult = IDNOACTION; | ||
| 608 | m_nLastNetfxFilesInUseResult = IDNOACTION; | ||
| 607 | 609 | ||
| 608 | return __super::OnApplyBegin(dwPhaseCount, pfCancel); | 610 | return __super::OnApplyBegin(dwPhaseCount, pfCancel); |
| 609 | } | 611 | } |
| @@ -1049,15 +1051,15 @@ public: // IBootstrapperApplication | |||
| 1049 | 1051 | ||
| 1050 | if (!m_fShowingInternalUiThisPackage && !m_fPrereq && wzPackageId && *wzPackageId) | 1052 | if (!m_fShowingInternalUiThisPackage && !m_fPrereq && wzPackageId && *wzPackageId) |
| 1051 | { | 1053 | { |
| 1052 | // If this is an MSI package, display the files-in-use dialog. | 1054 | BalLog(BOOTSTRAPPER_LOG_LEVEL_VERBOSE, "Package %ls has %d applications holding files in use.", wzPackageId, cFiles); |
| 1053 | BAL_INFO_PACKAGE* pPackage = NULL; | ||
| 1054 | BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage); | ||
| 1055 | 1055 | ||
| 1056 | if (pPackage && BAL_INFO_PACKAGE_TYPE_MSI == pPackage->type) | 1056 | switch (source) |
| 1057 | { | 1057 | { |
| 1058 | BalLog(BOOTSTRAPPER_LOG_LEVEL_VERBOSE, "Package %ls has %d applications holding files in use.", wzPackageId, cFiles); | 1058 | case BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI: |
| 1059 | 1059 | case BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI_RM: | |
| 1060 | return ShowFilesInUse(cFiles, rgwzFiles, source); | 1060 | return ShowMsiFilesInUse(cFiles, rgwzFiles, source, pResult); |
| 1061 | case BOOTSTRAPPER_FILES_IN_USE_TYPE_NETFX: | ||
| 1062 | return ShowNetfxFilesInUse(cFiles, rgwzFiles, pResult); | ||
| 1061 | } | 1063 | } |
| 1062 | } | 1064 | } |
| 1063 | 1065 | ||
| @@ -2213,10 +2215,11 @@ private: // privates | |||
| 2213 | } | 2215 | } |
| 2214 | 2216 | ||
| 2215 | 2217 | ||
| 2216 | int ShowFilesInUse( | 2218 | HRESULT ShowMsiFilesInUse( |
| 2217 | __in DWORD cFiles, | 2219 | __in DWORD cFiles, |
| 2218 | __in_ecount_z(cFiles) LPCWSTR* rgwzFiles, | 2220 | __in_ecount_z(cFiles) LPCWSTR* rgwzFiles, |
| 2219 | __in BOOTSTRAPPER_FILES_IN_USE_TYPE /*source*/ | 2221 | __in BOOTSTRAPPER_FILES_IN_USE_TYPE source, |
| 2222 | __inout int* pResult | ||
| 2220 | ) | 2223 | ) |
| 2221 | { | 2224 | { |
| 2222 | HRESULT hr = S_OK; | 2225 | HRESULT hr = S_OK; |
| @@ -2226,9 +2229,9 @@ private: // privates | |||
| 2226 | 2229 | ||
| 2227 | // If the user has chosen to ignore on a previously displayed "files in use" page, | 2230 | // If the user has chosen 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. | 2231 | // we will return the same result for other cases. No need to display the page again. |
| 2229 | if (IDIGNORE == m_nLastFilesInUseResult) | 2232 | if (IDIGNORE == m_nLastMsiFilesInUseResult) |
| 2230 | { | 2233 | { |
| 2231 | nResult = m_nLastFilesInUseResult; | 2234 | nResult = m_nLastMsiFilesInUseResult; |
| 2232 | } | 2235 | } |
| 2233 | else if (BOOTSTRAPPER_DISPLAY_FULL == m_command.display) // Only show files in use when using full display mode. | 2236 | else if (BOOTSTRAPPER_DISPLAY_FULL == m_command.display) // Only show files in use when using full display mode. |
| 2234 | { | 2237 | { |
| @@ -2246,8 +2249,16 @@ private: // privates | |||
| 2246 | } | 2249 | } |
| 2247 | 2250 | ||
| 2248 | // Show applications using the files. | 2251 | // Show applications using the files. |
| 2249 | hr = ShowFilesInUseDialog(sczFilesInUse, &nResult); | 2252 | if (BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI_RM == source) |
| 2250 | ExitOnFailure(hr, "Failed to show files-in-use task dialog."); | 2253 | { |
| 2254 | hr = ShowRestartManagerMsiFilesInUseDialog(sczFilesInUse, &nResult); | ||
| 2255 | ExitOnFailure(hr, "Failed to show RM files-in-use dialog."); | ||
| 2256 | } | ||
| 2257 | else | ||
| 2258 | { | ||
| 2259 | hr = ShowStandardMsiFilesInUseDialog(sczFilesInUse, &nResult); | ||
| 2260 | ExitOnFailure(hr, "Failed to show files-in-use dialog."); | ||
| 2261 | } | ||
| 2251 | } | 2262 | } |
| 2252 | else | 2263 | else |
| 2253 | { | 2264 | { |
| @@ -2260,13 +2271,14 @@ private: // privates | |||
| 2260 | ReleaseStr(sczFilesInUse); | 2271 | ReleaseStr(sczFilesInUse); |
| 2261 | 2272 | ||
| 2262 | // Remember the answer from the user. | 2273 | // Remember the answer from the user. |
| 2263 | m_nLastFilesInUseResult = FAILED(hr) ? IDERROR : nResult; | 2274 | m_nLastMsiFilesInUseResult = FAILED(hr) ? IDERROR : nResult; |
| 2275 | *pResult = m_nLastMsiFilesInUseResult; | ||
| 2264 | 2276 | ||
| 2265 | return m_nLastFilesInUseResult; | 2277 | return hr; |
| 2266 | } | 2278 | } |
| 2267 | 2279 | ||
| 2268 | 2280 | ||
| 2269 | int ShowFilesInUseDialog( | 2281 | int ShowRestartManagerMsiFilesInUseDialog( |
| 2270 | __in_z_opt LPCWSTR sczFilesInUse, | 2282 | __in_z_opt LPCWSTR sczFilesInUse, |
| 2271 | __out int* pnResult | 2283 | __out int* pnResult |
| 2272 | ) | 2284 | ) |
| @@ -2283,28 +2295,28 @@ private: // privates | |||
| 2283 | 2295 | ||
| 2284 | // Get the loc strings for the files-in-use task dialog text. | 2296 | // Get the loc strings for the files-in-use task dialog text. |
| 2285 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseTitle)", &pLocString); | 2297 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseTitle)", &pLocString); |
| 2286 | ExitOnFailure(hr, "Failed to get FilesInUseTitle loc string."); | 2298 | BalExitOnFailure(hr, "Failed to get FilesInUseTitle loc string."); |
| 2287 | 2299 | ||
| 2288 | hr = StrAllocString(&sczTitle, pLocString->wzText, 0); | 2300 | hr = StrAllocString(&sczTitle, pLocString->wzText, 0); |
| 2289 | ExitOnFailure(hr, "Failed to copy FilesInUseTitle loc string."); | 2301 | BalExitOnFailure(hr, "Failed to copy FilesInUseTitle loc string."); |
| 2290 | 2302 | ||
| 2291 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseLabel)", &pLocString); | 2303 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseLabel)", &pLocString); |
| 2292 | ExitOnFailure(hr, "Failed to get FilesInUseLabel loc string."); | 2304 | BalExitOnFailure(hr, "Failed to get FilesInUseLabel loc string."); |
| 2293 | 2305 | ||
| 2294 | hr = StrAllocString(&sczLabel, pLocString->wzText, 0); | 2306 | hr = StrAllocString(&sczLabel, pLocString->wzText, 0); |
| 2295 | ExitOnFailure(hr, "Failed to copy FilesInUseLabel loc string."); | 2307 | BalExitOnFailure(hr, "Failed to copy FilesInUseLabel loc string."); |
| 2296 | 2308 | ||
| 2297 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseCloseRadioButton)", &pLocString); | 2309 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseCloseRadioButton)", &pLocString); |
| 2298 | ExitOnFailure(hr, "Failed to get FilesInUseCloseRadioButton loc string."); | 2310 | BalExitOnFailure(hr, "Failed to get FilesInUseCloseRadioButton loc string."); |
| 2299 | 2311 | ||
| 2300 | hr = StrAllocString(&sczCloseRadioButton, pLocString->wzText, 0); | 2312 | hr = StrAllocString(&sczCloseRadioButton, pLocString->wzText, 0); |
| 2301 | ExitOnFailure(hr, "Failed to copy FilesInUseCloseRadioButton loc string."); | 2313 | BalExitOnFailure(hr, "Failed to copy FilesInUseCloseRadioButton loc string."); |
| 2302 | 2314 | ||
| 2303 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseDontCloseRadioButton)", &pLocString); | 2315 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseDontCloseRadioButton)", &pLocString); |
| 2304 | ExitOnFailure(hr, "Failed to get FilesInUseDontCloseRadioButton loc string."); | 2316 | BalExitOnFailure(hr, "Failed to get FilesInUseDontCloseRadioButton loc string."); |
| 2305 | 2317 | ||
| 2306 | hr = StrAllocString(&sczDontCloseRadioButton, pLocString->wzText, 0); | 2318 | hr = StrAllocString(&sczDontCloseRadioButton, pLocString->wzText, 0); |
| 2307 | ExitOnFailure(hr, "Failed to copy FilesInUseDontCloseRadioButton loc string."); | 2319 | BalExitOnFailure(hr, "Failed to copy FilesInUseDontCloseRadioButton loc string."); |
| 2308 | 2320 | ||
| 2309 | const TASKDIALOG_BUTTON rgRadioButtons[] = { | 2321 | const TASKDIALOG_BUTTON rgRadioButtons[] = { |
| 2310 | { IDOK, sczCloseRadioButton }, | 2322 | { IDOK, sczCloseRadioButton }, |
| @@ -2325,12 +2337,208 @@ private: // privates | |||
| 2325 | config.nDefaultRadioButton = IDOK; | 2337 | config.nDefaultRadioButton = IDOK; |
| 2326 | 2338 | ||
| 2327 | hr = ::TaskDialogIndirect(&config, &nButton, &nRadioButton, NULL); | 2339 | hr = ::TaskDialogIndirect(&config, &nButton, &nRadioButton, NULL); |
| 2328 | ExitOnFailure(hr, "Failed to show files-in-use task dialog."); | 2340 | BalExitOnFailure(hr, "Failed to show RM files-in-use task dialog."); |
| 2341 | |||
| 2342 | *pnResult = IDOK == nButton ? nRadioButton : nButton; | ||
| 2343 | |||
| 2344 | #ifdef DEBUG | ||
| 2345 | BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: RMFilesInUse task dialog result: button - %d, radio button - %d, result - %d", nButton, nRadioButton, *pnResult); | ||
| 2346 | #endif | ||
| 2347 | |||
| 2348 | LExit: | ||
| 2349 | return hr; | ||
| 2350 | } | ||
| 2351 | |||
| 2352 | |||
| 2353 | int ShowStandardMsiFilesInUseDialog( | ||
| 2354 | __in_z_opt LPCWSTR sczFilesInUse, | ||
| 2355 | __out int* pnResult | ||
| 2356 | ) | ||
| 2357 | { | ||
| 2358 | HRESULT hr = S_OK; | ||
| 2359 | TASKDIALOGCONFIG config = { }; | ||
| 2360 | LPWSTR sczTitle = NULL; | ||
| 2361 | LPWSTR sczLabel = NULL; | ||
| 2362 | LPWSTR sczRetryButton = NULL; | ||
| 2363 | LPWSTR sczIgnoreButton = NULL; | ||
| 2364 | LPWSTR sczExitButton = NULL; | ||
| 2365 | LOC_STRING* pLocString = NULL; | ||
| 2366 | |||
| 2367 | // Get the loc strings for the files-in-use task dialog text. | ||
| 2368 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseTitle)", &pLocString); | ||
| 2369 | BalExitOnFailure(hr, "Failed to get FilesInUseTitle loc string."); | ||
| 2370 | |||
| 2371 | hr = StrAllocString(&sczTitle, pLocString->wzText, 0); | ||
| 2372 | BalExitOnFailure(hr, "Failed to copy FilesInUseTitle loc string."); | ||
| 2373 | |||
| 2374 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseLabel)", &pLocString); | ||
| 2375 | BalExitOnFailure(hr, "Failed to get FilesInUseLabel loc string."); | ||
| 2376 | |||
| 2377 | hr = StrAllocString(&sczLabel, pLocString->wzText, 0); | ||
| 2378 | BalExitOnFailure(hr, "Failed to copy FilesInUseLabel loc string."); | ||
| 2379 | |||
| 2380 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseRetryButton)", &pLocString); | ||
| 2381 | BalExitOnFailure(hr, "Failed to get FilesInUseRetryButton loc string."); | ||
| 2382 | |||
| 2383 | hr = StrAllocString(&sczRetryButton, pLocString->wzText, 0); | ||
| 2384 | BalExitOnFailure(hr, "Failed to copy FilesInUseRetryButton loc string."); | ||
| 2385 | |||
| 2386 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseIgnoreButton)", &pLocString); | ||
| 2387 | BalExitOnFailure(hr, "Failed to get FilesInUseIgnoreButton loc string."); | ||
| 2388 | |||
| 2389 | hr = StrAllocString(&sczIgnoreButton, pLocString->wzText, 0); | ||
| 2390 | BalExitOnFailure(hr, "Failed to copy FilesInUseIgnoreButton loc string."); | ||
| 2391 | |||
| 2392 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseExitButton)", &pLocString); | ||
| 2393 | BalExitOnFailure(hr, "Failed to get FilesInUseExitButton loc string."); | ||
| 2394 | |||
| 2395 | hr = StrAllocString(&sczExitButton, pLocString->wzText, 0); | ||
| 2396 | BalExitOnFailure(hr, "Failed to copy FilesInUseExitButton loc string."); | ||
| 2397 | |||
| 2398 | const TASKDIALOG_BUTTON rgButtons[] = { | ||
| 2399 | { IDRETRY, sczRetryButton }, | ||
| 2400 | { IDIGNORE, sczIgnoreButton }, | ||
| 2401 | { IDCANCEL, sczExitButton }, | ||
| 2402 | }; | ||
| 2403 | |||
| 2404 | config.cbSize = sizeof(config); | ||
| 2405 | config.hwndParent = m_hWnd; | ||
| 2406 | config.hInstance = m_hModule; | ||
| 2407 | config.dwFlags = TDF_SIZE_TO_CONTENT | TDF_POSITION_RELATIVE_TO_WINDOW; | ||
| 2408 | config.pszWindowTitle = sczTitle; | ||
| 2409 | config.pszMainInstruction = sczLabel; | ||
| 2410 | config.pszContent = sczFilesInUse ? sczFilesInUse : L""; | ||
| 2411 | config.pButtons = rgButtons; | ||
| 2412 | config.cButtons = countof(rgButtons); | ||
| 2413 | |||
| 2414 | hr = ::TaskDialogIndirect(&config, pnResult, NULL, NULL); | ||
| 2415 | BalExitOnFailure(hr, "Failed to show files-in-use task dialog."); | ||
| 2416 | |||
| 2417 | #ifdef DEBUG | ||
| 2418 | BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: FilesInUse task dialog result: %d", *pnResult); | ||
| 2419 | #endif | ||
| 2420 | |||
| 2421 | LExit: | ||
| 2422 | return hr; | ||
| 2423 | } | ||
| 2424 | |||
| 2425 | |||
| 2426 | HRESULT ShowNetfxFilesInUse( | ||
| 2427 | __in DWORD cFiles, | ||
| 2428 | __in_ecount_z(cFiles) LPCWSTR* rgwzFiles, | ||
| 2429 | __inout int* pResult | ||
| 2430 | ) | ||
| 2431 | { | ||
| 2432 | HRESULT hr = S_OK; | ||
| 2433 | LPWSTR sczFilesInUse = NULL; | ||
| 2434 | DWORD_PTR cchLen = 0; | ||
| 2435 | int nResult = IDERROR; | ||
| 2436 | |||
| 2437 | // If the user has chosen to ignore on a previously displayed "files in use" page, | ||
| 2438 | // we will return the same result for other cases. No need to display the page again. | ||
| 2439 | if (IDNO == m_nLastNetfxFilesInUseResult) | ||
| 2440 | { | ||
| 2441 | nResult = m_nLastNetfxFilesInUseResult; | ||
| 2442 | } | ||
| 2443 | else if (BOOTSTRAPPER_DISPLAY_FULL != m_command.display) // Only show files in use when using full display mode. | ||
| 2444 | { | ||
| 2445 | nResult = IDYES; | ||
| 2446 | } | ||
| 2447 | else | ||
| 2448 | { | ||
| 2449 | for (DWORD i = 0; i < cFiles; ++i) | ||
| 2450 | { | ||
| 2451 | hr = ::StringCchLengthW(rgwzFiles[i], STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchLen)); | ||
| 2452 | BalExitOnFailure(hr, "Failed to calculate length of string."); | ||
| 2453 | |||
| 2454 | if (cchLen) | ||
| 2455 | { | ||
| 2456 | hr = StrAllocConcatFormatted(&sczFilesInUse, L"%ls\r\n", rgwzFiles[i]); | ||
| 2457 | BalExitOnFailure(hr, "Failed to concat files in use."); | ||
| 2458 | } | ||
| 2459 | } | ||
| 2460 | |||
| 2461 | // Show applications using the files. | ||
| 2462 | hr = ShowNetfxFilesInUseDialog(sczFilesInUse, &nResult); | ||
| 2463 | ExitOnFailure(hr, "Failed to show Netfx files-in-use dialog."); | ||
| 2464 | } | ||
| 2465 | |||
| 2466 | LExit: | ||
| 2467 | ReleaseStr(sczFilesInUse); | ||
| 2468 | |||
| 2469 | // Remember the answer from the user. | ||
| 2470 | m_nLastNetfxFilesInUseResult = FAILED(hr) ? IDERROR : nResult; | ||
| 2471 | *pResult = m_nLastNetfxFilesInUseResult; | ||
| 2472 | |||
| 2473 | return hr; | ||
| 2474 | } | ||
| 2475 | |||
| 2476 | |||
| 2477 | int ShowNetfxFilesInUseDialog( | ||
| 2478 | __in_z_opt LPCWSTR sczFilesInUse, | ||
| 2479 | __out int* pnResult | ||
| 2480 | ) | ||
| 2481 | { | ||
| 2482 | HRESULT hr = S_OK; | ||
| 2483 | TASKDIALOGCONFIG config = { }; | ||
| 2484 | LPWSTR sczTitle = NULL; | ||
| 2485 | LPWSTR sczLabel = NULL; | ||
| 2486 | LPWSTR sczNetfxCloseRadioButton = NULL; | ||
| 2487 | LPWSTR sczDontCloseRadioButton = NULL; | ||
| 2488 | LOC_STRING* pLocString = NULL; | ||
| 2489 | int nButton = 0; | ||
| 2490 | int nRadioButton = 0; | ||
| 2491 | |||
| 2492 | // Get the loc strings for the files-in-use task dialog text. | ||
| 2493 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseTitle)", &pLocString); | ||
| 2494 | BalExitOnFailure(hr, "Failed to get FilesInUseTitle loc string."); | ||
| 2495 | |||
| 2496 | hr = StrAllocString(&sczTitle, pLocString->wzText, 0); | ||
| 2497 | BalExitOnFailure(hr, "Failed to copy FilesInUseTitle loc string."); | ||
| 2498 | |||
| 2499 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseLabel)", &pLocString); | ||
| 2500 | BalExitOnFailure(hr, "Failed to get FilesInUseLabel loc string."); | ||
| 2501 | |||
| 2502 | hr = StrAllocString(&sczLabel, pLocString->wzText, 0); | ||
| 2503 | BalExitOnFailure(hr, "Failed to copy FilesInUseLabel loc string."); | ||
| 2504 | |||
| 2505 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseNetfxCloseRadioButton)", &pLocString); | ||
| 2506 | BalExitOnFailure(hr, "Failed to get FilesInUseNetfxCloseRadioButton loc string."); | ||
| 2507 | |||
| 2508 | hr = StrAllocString(&sczNetfxCloseRadioButton, pLocString->wzText, 0); | ||
| 2509 | BalExitOnFailure(hr, "Failed to copy FilesInUseNetfxCloseRadioButton loc string."); | ||
| 2510 | |||
| 2511 | hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseDontCloseRadioButton)", &pLocString); | ||
| 2512 | BalExitOnFailure(hr, "Failed to get FilesInUseDontCloseRadioButton loc string."); | ||
| 2513 | |||
| 2514 | hr = StrAllocString(&sczDontCloseRadioButton, pLocString->wzText, 0); | ||
| 2515 | BalExitOnFailure(hr, "Failed to copy FilesInUseDontCloseRadioButton loc string."); | ||
| 2516 | |||
| 2517 | const TASKDIALOG_BUTTON rgRadioButtons[] = { | ||
| 2518 | { IDYES, sczNetfxCloseRadioButton }, | ||
| 2519 | { IDNO, sczDontCloseRadioButton }, | ||
| 2520 | }; | ||
| 2521 | |||
| 2522 | config.cbSize = sizeof(config); | ||
| 2523 | config.hwndParent = m_hWnd; | ||
| 2524 | config.hInstance = m_hModule; | ||
| 2525 | config.dwFlags = TDF_SIZE_TO_CONTENT | TDF_POSITION_RELATIVE_TO_WINDOW; | ||
| 2526 | config.dwCommonButtons = TDCBF_RETRY_BUTTON | TDCBF_OK_BUTTON | TDCBF_CANCEL_BUTTON; | ||
| 2527 | config.pszWindowTitle = sczTitle; | ||
| 2528 | config.pszMainInstruction = sczLabel; | ||
| 2529 | config.pszContent = sczFilesInUse ? sczFilesInUse : L""; | ||
| 2530 | config.nDefaultButton = IDRETRY; | ||
| 2531 | config.pRadioButtons = rgRadioButtons; | ||
| 2532 | config.cRadioButtons = countof(rgRadioButtons); | ||
| 2533 | config.nDefaultRadioButton = IDYES; | ||
| 2534 | |||
| 2535 | hr = ::TaskDialogIndirect(&config, &nButton, &nRadioButton, NULL); | ||
| 2536 | BalExitOnFailure(hr, "Failed to show Netfx files-in-use task dialog."); | ||
| 2329 | 2537 | ||
| 2330 | *pnResult = IDOK == nButton ? nRadioButton : nButton; | 2538 | *pnResult = IDOK == nButton ? nRadioButton : nButton; |
| 2331 | 2539 | ||
| 2332 | #ifdef DEBUG | 2540 | #ifdef DEBUG |
| 2333 | BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: FilesInUse task dialog result: button - %d, radio button - %d, result - %d", nButton, nRadioButton, *pnResult); | 2541 | BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: NetfxFilesInUse task dialog result: button - %d, radio button - %d, result - %d", nButton, nRadioButton, *pnResult); |
| 2334 | #endif | 2542 | #endif |
| 2335 | 2543 | ||
| 2336 | LExit: | 2544 | LExit: |
| @@ -4423,7 +4631,8 @@ public: | |||
| 4423 | m_fPrereqInstalled = FALSE; | 4631 | m_fPrereqInstalled = FALSE; |
| 4424 | m_fPrereqSkipped = FALSE; | 4632 | m_fPrereqSkipped = FALSE; |
| 4425 | 4633 | ||
| 4426 | m_nLastFilesInUseResult = IDNOACTION; | 4634 | m_nLastMsiFilesInUseResult = IDNOACTION; |
| 4635 | m_nLastNetfxFilesInUseResult = IDNOACTION; | ||
| 4427 | 4636 | ||
| 4428 | pEngine->AddRef(); | 4637 | pEngine->AddRef(); |
| 4429 | m_pEngine = pEngine; | 4638 | m_pEngine = pEngine; |
| @@ -4717,7 +4926,8 @@ private: | |||
| 4717 | BOOL m_fShowingInternalUiThisPackage; | 4926 | BOOL m_fShowingInternalUiThisPackage; |
| 4718 | BOOL m_fTriedToLaunchElevated; | 4927 | BOOL m_fTriedToLaunchElevated; |
| 4719 | 4928 | ||
| 4720 | int m_nLastFilesInUseResult; | 4929 | int m_nLastMsiFilesInUseResult; |
| 4930 | int m_nLastNetfxFilesInUseResult; | ||
| 4721 | 4931 | ||
| 4722 | HMODULE m_hBAFModule; | 4932 | HMODULE m_hBAFModule; |
| 4723 | PFN_BA_FUNCTIONS_PROC m_pfnBAFunctionsProc; | 4933 | PFN_BA_FUNCTIONS_PROC m_pfnBAFunctionsProc; |
