diff options
| author | Charles Baker <charles@juicelabs.co> | 2024-10-24 13:13:26 +1300 |
|---|---|---|
| committer | Rob Mensching <rob@firegiant.com> | 2026-01-02 16:21:49 -0800 |
| commit | cd46cf04280d9b27fb271393a7aeb8289fe9c43c (patch) | |
| tree | a69ccd128100a24ec4501db0c10cd794e583cdc6 | |
| parent | 2a58247b62bdea7c829ca643812faa7665f39a73 (diff) | |
| download | wix-robmen/add-display-files-in-use-dialog-attribute.tar.gz wix-robmen/add-display-files-in-use-dialog-attribute.tar.bz2 wix-robmen/add-display-files-in-use-dialog-attribute.zip | |
Add bal:DisplayFilesInUseDialogCondition to disable Files In Use dialogrobmen/add-display-files-in-use-dialog-attribute
Disabling display skips showing the "Files In Use" dialog and returning
a result as if the user had chosen to ignore the dialog and reboot in
the case of files that were unable to be replaced.
15 files changed, 169 insertions, 20 deletions
diff --git a/src/api/burn/WixToolset.BootstrapperApplicationApi/IPackageInfo.cs b/src/api/burn/WixToolset.BootstrapperApplicationApi/IPackageInfo.cs index e2512584..9b5e74cb 100644 --- a/src/api/burn/WixToolset.BootstrapperApplicationApi/IPackageInfo.cs +++ b/src/api/burn/WixToolset.BootstrapperApplicationApi/IPackageInfo.cs | |||
| @@ -28,6 +28,11 @@ namespace WixToolset.BootstrapperApplicationApi | |||
| 28 | string DisplayInternalUICondition { get; } | 28 | string DisplayInternalUICondition { get; } |
| 29 | 29 | ||
| 30 | /// <summary> | 30 | /// <summary> |
| 31 | /// The authored bal:DisplayFilesInUseDialogCondition. | ||
| 32 | /// </summary> | ||
| 33 | string DisplayFilesInUseDialogCondition { get; } | ||
| 34 | |||
| 35 | /// <summary> | ||
| 31 | /// The package's display name. | 36 | /// The package's display name. |
| 32 | /// </summary> | 37 | /// </summary> |
| 33 | string DisplayName { get; } | 38 | string DisplayName { get; } |
diff --git a/src/api/burn/WixToolset.BootstrapperApplicationApi/PackageInfo.cs b/src/api/burn/WixToolset.BootstrapperApplicationApi/PackageInfo.cs index e835f9ea..81a8869f 100644 --- a/src/api/burn/WixToolset.BootstrapperApplicationApi/PackageInfo.cs +++ b/src/api/burn/WixToolset.BootstrapperApplicationApi/PackageInfo.cs | |||
| @@ -121,6 +121,9 @@ namespace WixToolset.BootstrapperApplicationApi | |||
| 121 | public string DisplayInternalUICondition { get; internal set; } | 121 | public string DisplayInternalUICondition { get; internal set; } |
| 122 | 122 | ||
| 123 | /// <inheritdoc/> | 123 | /// <inheritdoc/> |
| 124 | public string DisplayFilesInUseDialogCondition { get; internal set; } | ||
| 125 | |||
| 126 | /// <inheritdoc/> | ||
| 124 | public string ProductCode { get; internal set; } | 127 | public string ProductCode { get; internal set; } |
| 125 | 128 | ||
| 126 | /// <inheritdoc/> | 129 | /// <inheritdoc/> |
| @@ -363,6 +366,7 @@ namespace WixToolset.BootstrapperApplicationApi | |||
| 363 | var package = (PackageInfo)ipackage; | 366 | var package = (PackageInfo)ipackage; |
| 364 | 367 | ||
| 365 | package.DisplayInternalUICondition = BootstrapperApplicationData.GetAttribute(node, "DisplayInternalUICondition"); | 368 | package.DisplayInternalUICondition = BootstrapperApplicationData.GetAttribute(node, "DisplayInternalUICondition"); |
| 369 | package.DisplayFilesInUseDialogCondition = BootstrapperApplicationData.GetAttribute(node, "DisplayFilesInUseDialogCondition"); | ||
| 366 | } | 370 | } |
| 367 | 371 | ||
| 368 | nodes = root.Select("/p:BootstrapperApplicationData/p:WixPrereqInformation", namespaceManager); | 372 | nodes = root.Select("/p:BootstrapperApplicationData/p:WixPrereqInformation", namespaceManager); |
diff --git a/src/api/burn/balutil/balinfo.cpp b/src/api/burn/balutil/balinfo.cpp index 38c4bd18..ff0dfd9f 100644 --- a/src/api/burn/balutil/balinfo.cpp +++ b/src/api/burn/balutil/balinfo.cpp | |||
| @@ -291,6 +291,7 @@ DAPI_(void) BalInfoUninitialize( | |||
| 291 | ReleaseStr(pBundle->packages.rgPackages[i].sczDescription); | 291 | ReleaseStr(pBundle->packages.rgPackages[i].sczDescription); |
| 292 | ReleaseStr(pBundle->packages.rgPackages[i].sczId); | 292 | ReleaseStr(pBundle->packages.rgPackages[i].sczId); |
| 293 | ReleaseStr(pBundle->packages.rgPackages[i].sczDisplayInternalUICondition); | 293 | ReleaseStr(pBundle->packages.rgPackages[i].sczDisplayInternalUICondition); |
| 294 | ReleaseStr(pBundle->packages.rgPackages[i].sczDisplayFilesInUseDialogCondition); | ||
| 294 | ReleaseStr(pBundle->packages.rgPackages[i].sczProductCode); | 295 | ReleaseStr(pBundle->packages.rgPackages[i].sczProductCode); |
| 295 | ReleaseStr(pBundle->packages.rgPackages[i].sczUpgradeCode); | 296 | ReleaseStr(pBundle->packages.rgPackages[i].sczUpgradeCode); |
| 296 | ReleaseStr(pBundle->packages.rgPackages[i].sczVersion); | 297 | ReleaseStr(pBundle->packages.rgPackages[i].sczVersion); |
| @@ -517,6 +518,9 @@ static HRESULT ParseBalPackageInfoFromXml( | |||
| 517 | hr = XmlGetAttributeEx(pNode, L"DisplayInternalUICondition", &pPackage->sczDisplayInternalUICondition); | 518 | hr = XmlGetAttributeEx(pNode, L"DisplayInternalUICondition", &pPackage->sczDisplayInternalUICondition); |
| 518 | ExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get DisplayInternalUICondition setting for package."); | 519 | ExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get DisplayInternalUICondition setting for package."); |
| 519 | 520 | ||
| 521 | hr = XmlGetAttributeEx(pNode, L"DisplayFilesInUseDialogCondition", &pPackage->sczDisplayFilesInUseDialogCondition); | ||
| 522 | ExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get DisplayFilesInUseDialogCondition setting for package."); | ||
| 523 | |||
| 520 | hr = XmlGetAttributeEx(pNode, L"PrimaryPackageType", &scz); | 524 | hr = XmlGetAttributeEx(pNode, L"PrimaryPackageType", &scz); |
| 521 | ExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get PrimaryPackageType setting for package."); | 525 | ExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get PrimaryPackageType setting for package."); |
| 522 | 526 | ||
diff --git a/src/api/burn/balutil/inc/balinfo.h b/src/api/burn/balutil/inc/balinfo.h index 234284f6..8baee844 100644 --- a/src/api/burn/balutil/inc/balinfo.h +++ b/src/api/burn/balutil/inc/balinfo.h | |||
| @@ -54,6 +54,7 @@ typedef struct _BAL_INFO_PACKAGE | |||
| 54 | BOOL fPermanent; | 54 | BOOL fPermanent; |
| 55 | BOOL fVital; | 55 | BOOL fVital; |
| 56 | LPWSTR sczDisplayInternalUICondition; | 56 | LPWSTR sczDisplayInternalUICondition; |
| 57 | LPWSTR sczDisplayFilesInUseDialogCondition; | ||
| 57 | LPWSTR sczProductCode; | 58 | LPWSTR sczProductCode; |
| 58 | LPWSTR sczUpgradeCode; | 59 | LPWSTR sczUpgradeCode; |
| 59 | LPWSTR sczVersion; | 60 | LPWSTR sczVersion; |
diff --git a/src/ext/Bal/stdbas/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/stdbas/WixStandardBootstrapperApplication.cpp index 6cfe0b4c..ddb2d1c5 100644 --- a/src/ext/Bal/stdbas/WixStandardBootstrapperApplication.cpp +++ b/src/ext/Bal/stdbas/WixStandardBootstrapperApplication.cpp | |||
| @@ -1231,34 +1231,52 @@ public: // IBootstrapperApplication | |||
| 1231 | __inout int* pResult | 1231 | __inout int* pResult |
| 1232 | ) | 1232 | ) |
| 1233 | { | 1233 | { |
| 1234 | HRESULT hr = S_OK; | ||
| 1235 | BAL_INFO_PACKAGE* pPackage = NULL; | ||
| 1236 | BOOL fShowFilesInUseDialog = TRUE; | ||
| 1234 | 1237 | ||
| 1235 | if (!m_fShowingInternalUiThisPackage && wzPackageId && *wzPackageId) | 1238 | if (!m_fShowingInternalUiThisPackage && wzPackageId && *wzPackageId) |
| 1236 | { | 1239 | { |
| 1237 | BalLog(BOOTSTRAPPER_LOG_LEVEL_VERBOSE, "Package %ls has %d applications holding files in use.", wzPackageId, cFiles); | 1240 | BalLog(BOOTSTRAPPER_LOG_LEVEL_VERBOSE, "Package %ls has %d applications holding files in use.", wzPackageId, cFiles); |
| 1238 | 1241 | ||
| 1239 | switch (source) | 1242 | hr = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage); |
| 1243 | if (SUCCEEDED(hr) && pPackage->sczDisplayFilesInUseDialogCondition) | ||
| 1240 | { | 1244 | { |
| 1241 | case BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI: | 1245 | hr = BalEvaluateCondition(pPackage->sczDisplayFilesInUseDialogCondition, &fShowFilesInUseDialog); |
| 1242 | if (m_fShowStandardFilesInUse) | 1246 | BalExitOnFailure(hr, "Failed to evaluate condition for package '%ls': %ls", wzPackageId, pPackage->sczDisplayFilesInUseDialogCondition); |
| 1243 | { | 1247 | } |
| 1244 | return ShowMsiFilesInUse(cFiles, rgwzFiles, source, pResult); | 1248 | |
| 1245 | } | 1249 | if (fShowFilesInUseDialog) |
| 1246 | break; | 1250 | { |
| 1247 | case BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI_RM: | 1251 | switch (source) |
| 1248 | if (m_fShowRMFilesInUse) | ||
| 1249 | { | ||
| 1250 | return ShowMsiFilesInUse(cFiles, rgwzFiles, source, pResult); | ||
| 1251 | } | ||
| 1252 | break; | ||
| 1253 | case BOOTSTRAPPER_FILES_IN_USE_TYPE_NETFX: | ||
| 1254 | if (m_fShowNetfxFilesInUse) | ||
| 1255 | { | 1252 | { |
| 1256 | return ShowNetfxFilesInUse(cFiles, rgwzFiles, pResult); | 1253 | case BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI: |
| 1254 | if (m_fShowStandardFilesInUse) | ||
| 1255 | { | ||
| 1256 | return ShowMsiFilesInUse(cFiles, rgwzFiles, source, pResult); | ||
| 1257 | } | ||
| 1258 | break; | ||
| 1259 | case BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI_RM: | ||
| 1260 | if (m_fShowRMFilesInUse) | ||
| 1261 | { | ||
| 1262 | return ShowMsiFilesInUse(cFiles, rgwzFiles, source, pResult); | ||
| 1263 | } | ||
| 1264 | break; | ||
| 1265 | case BOOTSTRAPPER_FILES_IN_USE_TYPE_NETFX: | ||
| 1266 | if (m_fShowNetfxFilesInUse) | ||
| 1267 | { | ||
| 1268 | return ShowNetfxFilesInUse(cFiles, rgwzFiles, pResult); | ||
| 1269 | } | ||
| 1270 | break; | ||
| 1257 | } | 1271 | } |
| 1258 | break; | 1272 | } |
| 1273 | else | ||
| 1274 | { | ||
| 1275 | *pResult = IDIGNORE; | ||
| 1259 | } | 1276 | } |
| 1260 | } | 1277 | } |
| 1261 | 1278 | ||
| 1279 | LExit: | ||
| 1262 | return __super::OnExecuteFilesInUse(wzPackageId, cFiles, rgwzFiles, nRecommendation, source, pResult); | 1280 | return __super::OnExecuteFilesInUse(wzPackageId, cFiles, rgwzFiles, nRecommendation, source, pResult); |
| 1263 | } | 1281 | } |
| 1264 | 1282 | ||
diff --git a/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/BalExtensionFixture.cs b/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/BalExtensionFixture.cs index 07d3dacb..576e7c6c 100644 --- a/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/BalExtensionFixture.cs +++ b/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/BalExtensionFixture.cs | |||
| @@ -56,6 +56,44 @@ namespace WixToolsetTest.BootstrapperApplications | |||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | [TestMethod] | 58 | [TestMethod] |
| 59 | public void CanBuildUsingDisplayFilesInUseDialogCondition() | ||
| 60 | { | ||
| 61 | using (var fs = new DisposableFileSystem()) | ||
| 62 | { | ||
| 63 | var baseFolder = fs.GetFolder(); | ||
| 64 | var bundleFile = Path.Combine(baseFolder, "bin", "test.exe"); | ||
| 65 | var bundleSourceFolder = TestData.Get(@"TestData\WixStdBa"); | ||
| 66 | var intermediateFolder = Path.Combine(baseFolder, "obj"); | ||
| 67 | var baFolderPath = Path.Combine(baseFolder, "ba"); | ||
| 68 | var extractFolderPath = Path.Combine(baseFolder, "extract"); | ||
| 69 | |||
| 70 | var compileResult = WixRunner.Execute(new[] | ||
| 71 | { | ||
| 72 | "build", | ||
| 73 | Path.Combine(bundleSourceFolder, "DisplayFilesInUseDialogConditionBundle.wxs"), | ||
| 74 | "-ext", TestData.Get(@"WixToolset.BootstrapperApplications.wixext.dll"), | ||
| 75 | "-intermediateFolder", intermediateFolder, | ||
| 76 | "-bindpath", Path.Combine(bundleSourceFolder, "data"), | ||
| 77 | "-o", bundleFile, | ||
| 78 | }); | ||
| 79 | compileResult.AssertSuccess(); | ||
| 80 | |||
| 81 | Assert.IsTrue(File.Exists(bundleFile)); | ||
| 82 | |||
| 83 | var extractResult = BundleExtractor.ExtractBAContainer(null, bundleFile, baFolderPath, extractFolderPath); | ||
| 84 | extractResult.AssertSuccess(); | ||
| 85 | |||
| 86 | var balPackageInfos = extractResult.GetBADataTestXmlLines("/ba:BootstrapperApplicationData/ba:WixBalPackageInfo"); | ||
| 87 | WixAssert.CompareLineByLine(new string[] | ||
| 88 | { | ||
| 89 | "<WixBalPackageInfo PackageId='test.msi' DisplayFilesInUseDialogCondition='1' />", | ||
| 90 | }, balPackageInfos); | ||
| 91 | |||
| 92 | Assert.IsTrue(File.Exists(Path.Combine(baFolderPath, "thm.wxl"))); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | [TestMethod] | ||
| 59 | public void CanBuildUsingBootstrapperApplicationId() | 97 | public void CanBuildUsingBootstrapperApplicationId() |
| 60 | { | 98 | { |
| 61 | using (var fs = new DisposableFileSystem()) | 99 | using (var fs = new DisposableFileSystem()) |
| @@ -298,6 +336,7 @@ namespace WixToolsetTest.BootstrapperApplications | |||
| 298 | { | 336 | { |
| 299 | "bal:Condition/@Condition contains the built-in Variable 'WixBundleAction', which is not available when it is evaluated. (Unavailable Variables are: 'WixBundleAction'.). Rewrite the condition to avoid Variables that are never valid during its evaluation.", | 337 | "bal:Condition/@Condition contains the built-in Variable 'WixBundleAction', which is not available when it is evaluated. (Unavailable Variables are: 'WixBundleAction'.). Rewrite the condition to avoid Variables that are never valid during its evaluation.", |
| 300 | "Overridable variable 'TEST1' collides with 'Test1' with Bundle/@CommandLineVariables value 'caseInsensitive'.", | 338 | "Overridable variable 'TEST1' collides with 'Test1' with Bundle/@CommandLineVariables value 'caseInsensitive'.", |
| 339 | "The *Package/@bal:DisplayFilesInUseDialogCondition attribute's value '=' is not a valid bundle condition.", | ||
| 301 | "The *Package/@bal:DisplayInternalUICondition attribute's value '=' is not a valid bundle condition.", | 340 | "The *Package/@bal:DisplayInternalUICondition attribute's value '=' is not a valid bundle condition.", |
| 302 | "The location of the Variable related to the previous error.", | 341 | "The location of the Variable related to the previous error.", |
| 303 | }, messages.ToArray()); | 342 | }, messages.ToArray()); |
diff --git a/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/InternalUIBAFixture.cs b/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/InternalUIBAFixture.cs index 72e31540..7b4d00fc 100644 --- a/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/InternalUIBAFixture.cs +++ b/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/InternalUIBAFixture.cs | |||
| @@ -168,6 +168,7 @@ namespace WixToolsetTest.BootstrapperApplications | |||
| 168 | "WixInternalUIBootstrapperApplication does not support the value of 'force' for Cache on prereq packages. Prereq packages are only cached when they need to be installed.", | 168 | "WixInternalUIBootstrapperApplication does not support the value of 'force' for Cache on prereq packages. Prereq packages are only cached when they need to be installed.", |
| 169 | "WixInternalUIBootstrapperApplication ignores InstallCondition for the primary package so that the MSI UI is always shown.", | 169 | "WixInternalUIBootstrapperApplication ignores InstallCondition for the primary package so that the MSI UI is always shown.", |
| 170 | "WixInternalUIBootstrapperApplication ignores DisplayInternalUICondition for the primary package so that the MSI UI is always shown.", | 170 | "WixInternalUIBootstrapperApplication ignores DisplayInternalUICondition for the primary package so that the MSI UI is always shown.", |
| 171 | "WixInternalUIBootstrapperApplication ignores DisplayFilesInUseDialogCondition for the primary package so that the MSI UI is always shown.", | ||
| 171 | "When using WixInternalUIBootstrapperApplication, all prereq packages should be before the primary package in the chain. The prereq packages are always installed before the primary package.", | 172 | "When using WixInternalUIBootstrapperApplication, all prereq packages should be before the primary package in the chain. The prereq packages are always installed before the primary package.", |
| 172 | }, compileResult.Messages.Select(m => m.ToString()).ToArray()); | 173 | }, compileResult.Messages.Select(m => m.ToString()).ToArray()); |
| 173 | 174 | ||
| @@ -181,7 +182,7 @@ namespace WixToolsetTest.BootstrapperApplications | |||
| 181 | var balPackageInfos = extractResult.GetBADataTestXmlLines("/ba:BootstrapperApplicationData/ba:WixBalPackageInfo"); | 182 | var balPackageInfos = extractResult.GetBADataTestXmlLines("/ba:BootstrapperApplicationData/ba:WixBalPackageInfo"); |
| 182 | WixAssert.CompareLineByLine(new string[] | 183 | WixAssert.CompareLineByLine(new string[] |
| 183 | { | 184 | { |
| 184 | "<WixBalPackageInfo PackageId='test.msi' DisplayInternalUICondition='DISPLAYTEST' PrimaryPackageType='default' />", | 185 | "<WixBalPackageInfo PackageId='test.msi' DisplayInternalUICondition='DISPLAYTEST' DisplayFilesInUseDialogCondition='DISPLAYTEST' PrimaryPackageType='default' />", |
| 185 | }, balPackageInfos); | 186 | }, balPackageInfos); |
| 186 | 187 | ||
| 187 | var mbaPrereqInfos = extractResult.GetBADataTestXmlLines("/ba:BootstrapperApplicationData/ba:WixPrereqInformation"); | 188 | var mbaPrereqInfos = extractResult.GetBADataTestXmlLines("/ba:BootstrapperApplicationData/ba:WixPrereqInformation"); |
diff --git a/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/TestData/Overridable/WrongCaseBundle.wxs b/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/TestData/Overridable/WrongCaseBundle.wxs index 67dfc589..33b2d64c 100644 --- a/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/TestData/Overridable/WrongCaseBundle.wxs +++ b/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/TestData/Overridable/WrongCaseBundle.wxs | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | <Variable Name="TEST1" bal:Overridable="yes" /> | 9 | <Variable Name="TEST1" bal:Overridable="yes" /> |
| 10 | <Chain> | 10 | <Chain> |
| 11 | <ExePackage Permanent="yes" DetectCondition="none" SourceFile="runtimes\win-x86\native\wixnative.exe" /> | 11 | <ExePackage Permanent="yes" DetectCondition="none" SourceFile="runtimes\win-x86\native\wixnative.exe" /> |
| 12 | <MsiPackage SourceFile="test.msi" bal:DisplayInternalUICondition="!(loc.NonsensePlanCondition)" /> | 12 | <MsiPackage SourceFile="test.msi" bal:DisplayInternalUICondition="!(loc.NonsensePlanCondition)" bal:DisplayFilesInUseDialogCondition="!(loc.NonsensePlanCondition)" /> |
| 13 | </Chain> | 13 | </Chain> |
| 14 | <bal:Condition Condition="!(loc.NonsenseDetectCondition)" Message="Unsupported" /> | 14 | <bal:Condition Condition="!(loc.NonsenseDetectCondition)" Message="Unsupported" /> |
| 15 | </Bundle> | 15 | </Bundle> |
diff --git a/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/TestData/WixIuiBa/IuibaWarnings.wxs b/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/TestData/WixIuiBa/IuibaWarnings.wxs index 2cf9787d..9c9aa0f8 100644 --- a/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/TestData/WixIuiBa/IuibaWarnings.wxs +++ b/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/TestData/WixIuiBa/IuibaWarnings.wxs | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | <bal:WixInternalUIBootstrapperApplication /> | 6 | <bal:WixInternalUIBootstrapperApplication /> |
| 7 | </BootstrapperApplication> | 7 | </BootstrapperApplication> |
| 8 | <Chain> | 8 | <Chain> |
| 9 | <MsiPackage SourceFile="test.msi" InstallCondition="INSTALLTEST" bal:DisplayInternalUICondition="DISPLAYTEST" /> | 9 | <MsiPackage SourceFile="test.msi" InstallCondition="INSTALLTEST" bal:DisplayInternalUICondition="DISPLAYTEST" bal:DisplayFilesInUseDialogCondition="DISPLAYTEST" /> |
| 10 | <ExePackage Permanent="yes" DetectCondition="none" SourceFile="runtimes\win-x86\native\wixnative.exe" Cache="force" /> | 10 | <ExePackage Permanent="yes" DetectCondition="none" SourceFile="runtimes\win-x86\native\wixnative.exe" Cache="force" /> |
| 11 | </Chain> | 11 | </Chain> |
| 12 | </Bundle> | 12 | </Bundle> |
diff --git a/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/TestData/WixStdBa/DisplayFilesInUseDialogConditionBundle.wxs b/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/TestData/WixStdBa/DisplayFilesInUseDialogConditionBundle.wxs new file mode 100644 index 00000000..1041eb39 --- /dev/null +++ b/src/ext/Bal/test/WixToolsetTest.BootstrapperApplications/TestData/WixStdBa/DisplayFilesInUseDialogConditionBundle.wxs | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | <?xml version="1.0" encoding="utf-8"?> | ||
| 2 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" | ||
| 3 | xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal"> | ||
| 4 | <Bundle Name="WixStdBa" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="75D5D534-E177-4689-AAE9-CAC1C39002C2"> | ||
| 5 | <BootstrapperApplication> | ||
| 6 | <bal:WixStandardBootstrapperApplication LicenseUrl="http://wixtoolset.org/about/license/" Theme="hyperlinkLicense" /> | ||
| 7 | </BootstrapperApplication> | ||
| 8 | <Chain> | ||
| 9 | <MsiPackage SourceFile="test.msi" bal:DisplayFilesInUseDialogCondition="1" /> | ||
| 10 | </Chain> | ||
| 11 | </Bundle> | ||
| 12 | </Wix> | ||
diff --git a/src/ext/Bal/wixext/BalBurnBackendExtension.cs b/src/ext/Bal/wixext/BalBurnBackendExtension.cs index 82195549..5831bb8a 100644 --- a/src/ext/Bal/wixext/BalBurnBackendExtension.cs +++ b/src/ext/Bal/wixext/BalBurnBackendExtension.cs | |||
| @@ -51,6 +51,11 @@ namespace WixToolset.BootstrapperApplications | |||
| 51 | writer.WriteAttributeString("DisplayInternalUICondition", balPackageInfoSymbol.DisplayInternalUICondition); | 51 | writer.WriteAttributeString("DisplayInternalUICondition", balPackageInfoSymbol.DisplayInternalUICondition); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | if (balPackageInfoSymbol.DisplayFilesInUseDialogCondition != null) | ||
| 55 | { | ||
| 56 | writer.WriteAttributeString("DisplayFilesInUseDialogCondition", balPackageInfoSymbol.DisplayFilesInUseDialogCondition); | ||
| 57 | } | ||
| 58 | |||
| 54 | if (balPackageInfoSymbol.PrimaryPackageType != BalPrimaryPackageType.None) | 59 | if (balPackageInfoSymbol.PrimaryPackageType != BalPrimaryPackageType.None) |
| 55 | { | 60 | { |
| 56 | writer.WriteAttributeString("PrimaryPackageType", balPackageInfoSymbol.PrimaryPackageType.ToString().ToLower()); | 61 | writer.WriteAttributeString("PrimaryPackageType", balPackageInfoSymbol.PrimaryPackageType.ToString().ToLower()); |
| @@ -104,6 +109,7 @@ namespace WixToolset.BootstrapperApplications | |||
| 104 | 109 | ||
| 105 | this.VerifyBalConditions(section); | 110 | this.VerifyBalConditions(section); |
| 106 | this.VerifyDisplayInternalUICondition(section); | 111 | this.VerifyDisplayInternalUICondition(section); |
| 112 | this.VerifyDisplayFilesInUseDialogCondition(section); | ||
| 107 | this.VerifyOverridableVariables(section); | 113 | this.VerifyOverridableVariables(section); |
| 108 | 114 | ||
| 109 | var balBaSymbol = section.Symbols.OfType<WixBalBootstrapperApplicationSymbol>().SingleOrDefault(); | 115 | var balBaSymbol = section.Symbols.OfType<WixBalBootstrapperApplicationSymbol>().SingleOrDefault(); |
| @@ -195,6 +201,17 @@ namespace WixToolset.BootstrapperApplications | |||
| 195 | } | 201 | } |
| 196 | } | 202 | } |
| 197 | 203 | ||
| 204 | private void VerifyDisplayFilesInUseDialogCondition(IntermediateSection section) | ||
| 205 | { | ||
| 206 | foreach (var balPackageInfoSymbol in section.Symbols.OfType<WixBalPackageInfoSymbol>().ToList()) | ||
| 207 | { | ||
| 208 | if (balPackageInfoSymbol.DisplayFilesInUseDialogCondition != null) | ||
| 209 | { | ||
| 210 | this.BackendHelper.ValidateBundleCondition(balPackageInfoSymbol.SourceLineNumbers, "*Package", "bal:DisplayFilesInUseDialogCondition", balPackageInfoSymbol.DisplayFilesInUseDialogCondition, BundleConditionPhase.Plan); | ||
| 211 | } | ||
| 212 | } | ||
| 213 | } | ||
| 214 | |||
| 198 | private void VerifyPrimaryPackages(IntermediateSection section, SourceLineNumber baSourceLineNumbers) | 215 | private void VerifyPrimaryPackages(IntermediateSection section, SourceLineNumber baSourceLineNumbers) |
| 199 | { | 216 | { |
| 200 | WixBalPackageInfoSymbol defaultPrimaryPackage = null; | 217 | WixBalPackageInfoSymbol defaultPrimaryPackage = null; |
| @@ -420,6 +437,11 @@ namespace WixToolset.BootstrapperApplications | |||
| 420 | { | 437 | { |
| 421 | this.Messaging.Write(BalWarnings.IuibaPrimaryPackageDisplayInternalUICondition(packageSymbol.SourceLineNumbers)); | 438 | this.Messaging.Write(BalWarnings.IuibaPrimaryPackageDisplayInternalUICondition(packageSymbol.SourceLineNumbers)); |
| 422 | } | 439 | } |
| 440 | |||
| 441 | if (balPackageInfoSymbol.DisplayFilesInUseDialogCondition != null) | ||
| 442 | { | ||
| 443 | this.Messaging.Write(BalWarnings.IuibaPrimaryPackageDisplayFilesInUseDialogCondition(packageSymbol.SourceLineNumbers)); | ||
| 444 | } | ||
| 423 | } | 445 | } |
| 424 | 446 | ||
| 425 | private void VerifyOverridableVariables(IntermediateSection section) | 447 | private void VerifyOverridableVariables(IntermediateSection section) |
diff --git a/src/ext/Bal/wixext/BalCompiler.cs b/src/ext/Bal/wixext/BalCompiler.cs index 35c86233..b7d5f679 100644 --- a/src/ext/Bal/wixext/BalCompiler.cs +++ b/src/ext/Bal/wixext/BalCompiler.cs | |||
| @@ -200,6 +200,20 @@ namespace WixToolset.BootstrapperApplications | |||
| 200 | break; | 200 | break; |
| 201 | } | 201 | } |
| 202 | break; | 202 | break; |
| 203 | case "DisplayFilesInUseDialogCondition": | ||
| 204 | switch (parentElement.Name.LocalName) | ||
| 205 | { | ||
| 206 | case "MsiPackage": | ||
| 207 | case "MspPackage": | ||
| 208 | var displayFilesInUseDialogCondition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attribute); | ||
| 209 | var packageInfo = this.GetBalPackageInfoSymbol(section, sourceLineNumbers, packageId); | ||
| 210 | packageInfo.DisplayFilesInUseDialogCondition = displayFilesInUseDialogCondition; | ||
| 211 | break; | ||
| 212 | default: | ||
| 213 | this.ParseHelper.UnexpectedAttribute(parentElement, attribute); | ||
| 214 | break; | ||
| 215 | } | ||
| 216 | break; | ||
| 203 | case "PrimaryPackageType": | 217 | case "PrimaryPackageType": |
| 204 | { | 218 | { |
| 205 | var primaryPackageType = BalPrimaryPackageType.None; | 219 | var primaryPackageType = BalPrimaryPackageType.None; |
diff --git a/src/ext/Bal/wixext/BalWarnings.cs b/src/ext/Bal/wixext/BalWarnings.cs index 8c5d892f..f86837f9 100644 --- a/src/ext/Bal/wixext/BalWarnings.cs +++ b/src/ext/Bal/wixext/BalWarnings.cs | |||
| @@ -23,6 +23,11 @@ namespace WixToolset.BootstrapperApplications | |||
| 23 | return Message(sourceLineNumbers, Ids.IuibaPrimaryPackageDisplayInternalUICondition, "WixInternalUIBootstrapperApplication ignores DisplayInternalUICondition for the primary package so that the MSI UI is always shown."); | 23 | return Message(sourceLineNumbers, Ids.IuibaPrimaryPackageDisplayInternalUICondition, "WixInternalUIBootstrapperApplication ignores DisplayInternalUICondition for the primary package so that the MSI UI is always shown."); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | public static Message IuibaPrimaryPackageDisplayFilesInUseDialogCondition(SourceLineNumber sourceLineNumbers) | ||
| 27 | { | ||
| 28 | return Message(sourceLineNumbers, Ids.IuibaPrimaryPackageDisplayFilesInUseDialogCondition, "WixInternalUIBootstrapperApplication ignores DisplayFilesInUseDialogCondition for the primary package so that the MSI UI is always shown."); | ||
| 29 | } | ||
| 30 | |||
| 26 | public static Message IuibaPrimaryPackageInstallCondition(SourceLineNumber sourceLineNumbers) | 31 | public static Message IuibaPrimaryPackageInstallCondition(SourceLineNumber sourceLineNumbers) |
| 27 | { | 32 | { |
| 28 | return Message(sourceLineNumbers, Ids.IuibaPrimaryPackageInstallCondition, "WixInternalUIBootstrapperApplication ignores InstallCondition for the primary package so that the MSI UI is always shown."); | 33 | return Message(sourceLineNumbers, Ids.IuibaPrimaryPackageInstallCondition, "WixInternalUIBootstrapperApplication ignores InstallCondition for the primary package so that the MSI UI is always shown."); |
| @@ -56,6 +61,7 @@ namespace WixToolset.BootstrapperApplications | |||
| 56 | IuibaPrimaryPackageDisplayInternalUICondition = 6504, | 61 | IuibaPrimaryPackageDisplayInternalUICondition = 6504, |
| 57 | IuibaPrereqPackageAfterPrimaryPackage = 6505, | 62 | IuibaPrereqPackageAfterPrimaryPackage = 6505, |
| 58 | DeprecatedBAFactoryAssemblyAttribute = 6506, | 63 | DeprecatedBAFactoryAssemblyAttribute = 6506, |
| 64 | IuibaPrimaryPackageDisplayFilesInUseDialogCondition = 6507, | ||
| 59 | } | 65 | } |
| 60 | } | 66 | } |
| 61 | } | 67 | } |
diff --git a/src/ext/Bal/wixext/Symbols/WixBalPackageInfoSymbol.cs b/src/ext/Bal/wixext/Symbols/WixBalPackageInfoSymbol.cs index e2636d33..79773566 100644 --- a/src/ext/Bal/wixext/Symbols/WixBalPackageInfoSymbol.cs +++ b/src/ext/Bal/wixext/Symbols/WixBalPackageInfoSymbol.cs | |||
| @@ -13,6 +13,7 @@ namespace WixToolset.BootstrapperApplications | |||
| 13 | { | 13 | { |
| 14 | new IntermediateFieldDefinition(nameof(WixBalPackageInfoSymbolFields.PackageId), IntermediateFieldType.String), | 14 | new IntermediateFieldDefinition(nameof(WixBalPackageInfoSymbolFields.PackageId), IntermediateFieldType.String), |
| 15 | new IntermediateFieldDefinition(nameof(WixBalPackageInfoSymbolFields.DisplayInternalUICondition), IntermediateFieldType.String), | 15 | new IntermediateFieldDefinition(nameof(WixBalPackageInfoSymbolFields.DisplayInternalUICondition), IntermediateFieldType.String), |
| 16 | new IntermediateFieldDefinition(nameof(WixBalPackageInfoSymbolFields.DisplayFilesInUseDialogCondition), IntermediateFieldType.String), | ||
| 16 | new IntermediateFieldDefinition(nameof(WixBalPackageInfoSymbolFields.PrimaryPackageType), IntermediateFieldType.Number), | 17 | new IntermediateFieldDefinition(nameof(WixBalPackageInfoSymbolFields.PrimaryPackageType), IntermediateFieldType.Number), |
| 17 | }, | 18 | }, |
| 18 | typeof(WixBalPackageInfoSymbol)); | 19 | typeof(WixBalPackageInfoSymbol)); |
| @@ -28,6 +29,7 @@ namespace WixToolset.BootstrapperApplications.Symbols | |||
| 28 | PackageId, | 29 | PackageId, |
| 29 | DisplayInternalUICondition, | 30 | DisplayInternalUICondition, |
| 30 | PrimaryPackageType, | 31 | PrimaryPackageType, |
| 32 | DisplayFilesInUseDialogCondition, | ||
| 31 | } | 33 | } |
| 32 | 34 | ||
| 33 | public enum BalPrimaryPackageType | 35 | public enum BalPrimaryPackageType |
| @@ -63,6 +65,12 @@ namespace WixToolset.BootstrapperApplications.Symbols | |||
| 63 | set => this.Set((int)WixBalPackageInfoSymbolFields.DisplayInternalUICondition, value); | 65 | set => this.Set((int)WixBalPackageInfoSymbolFields.DisplayInternalUICondition, value); |
| 64 | } | 66 | } |
| 65 | 67 | ||
| 68 | public string DisplayFilesInUseDialogCondition | ||
| 69 | { | ||
| 70 | get => this.Fields[(int)WixBalPackageInfoSymbolFields.DisplayFilesInUseDialogCondition].AsString(); | ||
| 71 | set => this.Set((int)WixBalPackageInfoSymbolFields.DisplayFilesInUseDialogCondition, value); | ||
| 72 | } | ||
| 73 | |||
| 66 | public BalPrimaryPackageType PrimaryPackageType | 74 | public BalPrimaryPackageType PrimaryPackageType |
| 67 | { | 75 | { |
| 68 | get => (BalPrimaryPackageType)this.Fields[(int)WixBalPackageInfoSymbolFields.PrimaryPackageType].AsNumber(); | 76 | get => (BalPrimaryPackageType)this.Fields[(int)WixBalPackageInfoSymbolFields.PrimaryPackageType].AsNumber(); |
diff --git a/src/xsd/bal.xsd b/src/xsd/bal.xsd index ff4142ad..c7bd10fa 100644 --- a/src/xsd/bal.xsd +++ b/src/xsd/bal.xsd | |||
| @@ -623,6 +623,21 @@ | |||
| 623 | </xs:simpleType> | 623 | </xs:simpleType> |
| 624 | </xs:attribute> | 624 | </xs:attribute> |
| 625 | 625 | ||
| 626 | <xs:attribute name="DisplayFilesInUseDialogCondition" type="xs:string"> | ||
| 627 | <xs:annotation> | ||
| 628 | <xs:documentation> | ||
| 629 | Specifies whether the bundle will allow the Files In Use dialog to be displayed for the MSI or MSP package. If not | ||
| 630 | specified or the condition evaluates to true, the Files In Use dialog will be prompt the user during full UI to | ||
| 631 | close applications to release the file. Otherwise, the dialog will not be displayed and the package will likely | ||
| 632 | require a restart when files are in use. | ||
| 633 | </xs:documentation> | ||
| 634 | <xs:appinfo> | ||
| 635 | <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="MsiPackage" /> | ||
| 636 | <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="MspPackage" /> | ||
| 637 | </xs:appinfo> | ||
| 638 | </xs:annotation> | ||
| 639 | </xs:attribute> | ||
| 640 | |||
| 626 | <xs:attribute name="DisplayInternalUICondition" type="xs:string"> | 641 | <xs:attribute name="DisplayInternalUICondition" type="xs:string"> |
| 627 | <xs:annotation> | 642 | <xs:annotation> |
| 628 | <xs:documentation> | 643 | <xs:documentation> |
