aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Arnson <bob@firegiant.com>2024-08-26 00:20:06 -0400
committerRob Mensching <rob@firegiant.com>2024-12-26 21:46:38 -0800
commit3986a0b375d5b536f897d6284770baf711afaf86 (patch)
tree73534a0941f56dc8c1024c4655472b8948341a82
parent0ef9833f8559d8630f452e1c7e07ca057bab4523 (diff)
downloadwix-3986a0b375d5b536f897d6284770baf711afaf86.tar.gz
wix-3986a0b375d5b536f897d6284770baf711afaf86.tar.bz2
wix-3986a0b375d5b536f897d6284770baf711afaf86.zip
Replace EULA printing custom action with MsiPrint.
Fixes https://github.com/wixtoolset/issues/issues/8580
-rw-r--r--src/ext/UI/ca/PrintEula.cpp556
-rw-r--r--src/ext/UI/ca/uica.def1
-rw-r--r--src/ext/UI/ca/uica.vcxproj1
-rw-r--r--src/ext/UI/test/WixToolsetTest.UI/TestData/InstallDir_SpecialDlg/Package.wxs1
-rw-r--r--src/ext/UI/test/WixToolsetTest.UI/UIExtensionFixture.cs38
-rw-r--r--src/ext/UI/wixlib/AdvancedWelcomeEulaDlg.wxs4
-rw-r--r--src/ext/UI/wixlib/Common_Platform.wxi4
-rw-r--r--src/ext/UI/wixlib/LicenseAgreementDlg.wxs4
-rw-r--r--src/ext/UI/wixlib/WelcomeEulaDlg.wxs4
-rw-r--r--src/ext/UI/wixlib/WixUI_Advanced.wxs1
-rw-r--r--src/ext/UI/wixlib/WixUI_FeatureTree.wxs5
-rw-r--r--src/ext/UI/wixlib/WixUI_InstallDir.wxs1
-rw-r--r--src/ext/UI/wixlib/WixUI_Minimal.wxs5
-rw-r--r--src/ext/UI/wixlib/WixUI_Mondo.wxs1
-rw-r--r--src/wix/WixToolset.Converters/WixConverter.cs22
-rw-r--r--src/wix/test/WixToolsetTest.Converters/UIExtensionFixture.cs20
16 files changed, 42 insertions, 626 deletions
diff --git a/src/ext/UI/ca/PrintEula.cpp b/src/ext/UI/ca/PrintEula.cpp
deleted file mode 100644
index b19de9a6..00000000
--- a/src/ext/UI/ca/PrintEula.cpp
+++ /dev/null
@@ -1,556 +0,0 @@
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#include "precomp.h"
4
5// Constants
6LPCWSTR vcsEulaQuery = L"SELECT `Text` FROM `Control` WHERE `Control`='LicenseText'";
7
8
9enum eEulaQuery { eqText = 1};
10const int IDM_POPULATE = 100;
11const int IDM_PRINT = 101;
12const int CONTROL_X_COORDINATE = 0;
13const int CONTROL_Y_COORDINATE = 0;
14const int CONTROL_WIDTH = 500;
15const int CONTROL_HEIGHT = 500;
16const int ONE_INCH = 1440; // 1440 TWIPS = 1 inch.
17const int TEXT_RECORD_POS = 1;
18const int STRING_CAPACITY = 512;
19const int NO_OF_COPIES = 1;
20const LPWSTR WINDOW_CLASS = L"PrintEulaRichText";
21
22//Forward declarations of functions, check the function definitions for the comments
23static LRESULT CALLBACK WndProc(__in HWND hWnd, __in UINT message, __in WPARAM wParam, __in LPARAM lParam);
24static HRESULT ReadEulaText(__in MSIHANDLE hInstall, __out LPSTR* ppszEulaText);
25static DWORD CALLBACK ReadStreamCallback(__in DWORD Cookie, __out LPBYTE pbBuff, __in LONG cb, __out LONG FAR *pcb);
26static HRESULT CreateRichTextWindow(__out HWND* phWndMain, __out BOOL* pfRegisteredClass);
27static HRESULT PrintRichText(__in HWND hWndMain);
28static void Print(__in_opt HWND hWnd);
29static void LoadEulaText(__in_opt HWND hWnd);
30static void ShowErrorMessage(__in HRESULT hr);
31
32//Global variables
33PRINTDLGEXW* vpPrintDlg = NULL; //Parameters for print (needed on both sides of WndProc callbacks)
34LPSTR vpszEulaText = NULL;
35LPCWSTR vwzRichEditClass = NULL;
36HRESULT vhr = S_OK; //Global hr, used by the functions called from WndProc to set errorcode
37
38
39/********************************************************************
40 PrintEula - Custom Action entry point
41
42********************************************************************/
43extern "C" UINT __stdcall PrintEula(MSIHANDLE hInstall)
44{
45 //AssertSz(FALSE, "Debug PrintEula");
46
47 HRESULT hr = S_OK;
48 HWND hWndMain = NULL;
49 HMODULE hRichEdit = NULL;
50 BOOL fRegisteredClass = FALSE;
51
52 hr = WcaInitialize(hInstall, "PrintEula");
53 ExitOnFailure(hr, "failed to initialize");
54
55 // Initialize then display print dialog.
56 vpPrintDlg = (PRINTDLGEXW*)GlobalAlloc(GPTR, sizeof(PRINTDLGEXW)); // MSDN says to allocate on heap.
57 ExitOnNullWithLastError(vpPrintDlg, hr, "Failed to allocate memory for print dialog struct.");
58
59 vpPrintDlg->lStructSize = sizeof(PRINTDLGEX);
60 vpPrintDlg->hwndOwner = ::FindWindowW(L"MsiDialogCloseClass", NULL);
61 vpPrintDlg->Flags = PD_RETURNDC | PD_COLLATE | PD_NOCURRENTPAGE | PD_ALLPAGES | PD_NOPAGENUMS | PD_NOSELECTION;
62 vpPrintDlg->nCopies = NO_OF_COPIES;
63 vpPrintDlg->nStartPage = START_PAGE_GENERAL;
64
65 hr = ::PrintDlgExW(vpPrintDlg);
66 ExitOnFailure(hr, "Failed to show print dialog");
67
68 // If user said they want to print.
69 if (PD_RESULT_PRINT == vpPrintDlg->dwResultAction)
70 {
71 // Get the stream for Eula
72 hr = ReadEulaText(hInstall, &vpszEulaText);
73 ExitOnFailure(hr, "failed to read Eula text from MSI database");
74
75 // Have to load Rich Edit since we'll be creating a Rich Edit control in the window
76 hr = LoadSystemLibrary(L"Msftedit.dll", &hRichEdit);
77 if (SUCCEEDED(hr))
78 {
79 vwzRichEditClass = MSFTEDIT_CLASS;
80 }
81 else
82 {
83 hr = LoadSystemLibrary(L"Riched20.dll", &hRichEdit);
84 ExitOnFailure(hr, "failed to load rich edit 2.0 library");
85
86 vwzRichEditClass = RICHEDIT_CLASSW;
87 }
88
89 hr = CreateRichTextWindow(&hWndMain, &fRegisteredClass);
90 ExitOnFailure(hr, "failed to create rich text window for printing");
91
92 hr = PrintRichText(hWndMain);
93 if (FAILED(hr)) // Since we've already shown the print dialog, we better show them a dialog explaining why it didn't print
94 {
95 ShowErrorMessage(hr);
96 }
97 }
98
99LExit:
100 ReleaseNullStr(vpszEulaText);
101 if (vpPrintDlg)
102 {
103 if (vpPrintDlg->hDevMode)
104 {
105 ::GlobalFree(vpPrintDlg->hDevMode);
106 }
107
108 if (vpPrintDlg->hDevNames)
109 {
110 ::GlobalFree(vpPrintDlg->hDevNames);
111 }
112
113 if (vpPrintDlg->hDC)
114 {
115 ::DeleteDC(vpPrintDlg->hDC);
116 }
117
118 ::GlobalFree(vpPrintDlg);
119 vpPrintDlg = NULL;
120 }
121
122 if (fRegisteredClass)
123 {
124 ::UnregisterClassW(WINDOW_CLASS, NULL);
125 }
126
127 vwzRichEditClass = NULL;
128 if (NULL != hRichEdit)
129 {
130 ::FreeLibrary(hRichEdit);
131 }
132
133 // Always return success since we dont want to stop the
134 // installation even if the Eula printing fails.
135 return WcaFinalize(ERROR_SUCCESS);
136}
137
138
139
140/********************************************************************
141CreateRichTextWindow - Creates Window and Child RichText control.
142
143********************************************************************/
144HRESULT CreateRichTextWindow(
145 __out HWND* phWndMain,
146 __out BOOL* pfRegisteredClass
147 )
148{
149 HRESULT hr = S_OK;
150 HWND hWndMain = NULL;
151 WNDCLASSEXW wcex;
152
153 //
154 // Register the window class
155 //
156 wcex.cbSize = sizeof(WNDCLASSEXW);
157 wcex.style = CS_HREDRAW | CS_VREDRAW;
158 wcex.lpfnWndProc = (WNDPROC)WndProc;
159 wcex.cbClsExtra = 0;
160 wcex.cbWndExtra = 0;
161 wcex.hInstance = NULL;
162 wcex.hIcon = NULL;
163 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
164 wcex.hbrBackground = (HBRUSH)(COLOR_BACKGROUND+1);
165 wcex.lpszMenuName = NULL;
166 wcex.lpszClassName = WINDOW_CLASS;
167 wcex.hIconSm = NULL;
168
169 if (0 == ::RegisterClassExW(&wcex))
170 {
171 DWORD dwResult = ::GetLastError();
172
173 // If we get "Class already exists" error ignore it. We might
174 // encounter this when the user tries to print more than once
175 // in the same setup instance and we are unable to clean up fully.
176 if (dwResult != ERROR_CLASS_ALREADY_EXISTS)
177 {
178 ExitOnFailure(hr = HRESULT_FROM_WIN32(dwResult), "failed to register window class");
179 }
180 }
181
182 *pfRegisteredClass = TRUE;
183
184 // Perform application initialization:
185 hWndMain = ::CreateWindowW(WINDOW_CLASS, NULL, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, NULL, NULL);
186 ExitOnNullWithLastError(hWndMain, hr, "failed to create window for printing");
187
188 ::ShowWindow(hWndMain, SW_HIDE);
189 if (!::UpdateWindow(hWndMain))
190 {
191 ExitWithLastError(hr, "failed to update window");
192 }
193
194 *phWndMain = hWndMain;
195
196LExit:
197 return hr;
198}
199
200
201/********************************************************************
202 PrintRichText - Sends messages to load the Eula text, print it, and
203 close the window.
204
205 NOTE: Returns errors that have occured while attempting to print,
206 which were saved in vhr by the print callbacks.
207********************************************************************/
208HRESULT PrintRichText(
209 __in HWND hWndMain
210 )
211{
212 MSG msg;
213
214 // Populate the RichEdit control
215 ::SendMessageW(hWndMain, WM_COMMAND, IDM_POPULATE, 0);
216
217 // Print Eula
218 ::SendMessageW(hWndMain, WM_COMMAND, IDM_PRINT, 0);
219
220 // Done! Lets close the Window
221 ::SendMessage(hWndMain, WM_CLOSE, 0, 0);
222 // Main message loop:
223 while (::GetMessageW(&msg, NULL, 0, 0))
224 {
225// if (!::TranslateAcceleratorW(msg.hwnd, NULL, &msg))
226// {
227// ::TranslateMessage(&msg);
228// ::DispatchMessageW(&msg);
229// }
230 }
231
232
233 // return any errors encountered in the print callbacks
234 return vhr;
235}
236
237
238/********************************************************************
239 WndProc - Windows callback procedure
240
241********************************************************************/
242LRESULT CALLBACK WndProc(
243 __in HWND hWnd,
244 __in UINT message,
245 __in WPARAM wParam,
246 __in LPARAM lParam
247 )
248{
249 static HWND hWndRichEdit = NULL;
250 int wmId, wmEvent;
251 PAINTSTRUCT ps;
252 HDC hdc;
253
254 switch (message)
255 {
256 case WM_CREATE:
257 hWndRichEdit = ::CreateWindowExW(WS_EX_CLIENTEDGE, vwzRichEditClass, L"", ES_MULTILINE | WS_CHILD | WS_VISIBLE | WS_VSCROLL, CONTROL_X_COORDINATE, CONTROL_Y_COORDINATE, CONTROL_WIDTH, CONTROL_HEIGHT, hWnd, NULL, NULL, NULL);
258 break;
259 case WM_COMMAND:
260 wmId = LOWORD(wParam);
261 wmEvent = HIWORD(wParam);
262 switch (wmId)
263 {
264 case IDM_POPULATE:
265 LoadEulaText(hWndRichEdit);
266 break;
267 case IDM_PRINT:
268 Print(hWndRichEdit);
269 break;
270 default:
271 return ::DefWindowProcW(hWnd, message, wParam, lParam);
272 break;
273 }
274 break;
275 case WM_PAINT:
276 hdc = ::BeginPaint(hWnd, &ps);
277 ::EndPaint(hWnd, &ps);
278 break;
279 case WM_DESTROY:
280 ::PostQuitMessage(0);
281 break;
282 default:
283 return ::DefWindowProcW(hWnd, message, wParam, lParam);
284 }
285
286 return 0;
287}
288
289
290/********************************************************************
291 ReadStreamCallback - Callback function to read data to the RichText control
292
293 NOTE: Richtext control uses this function to read data from the buffer
294********************************************************************/
295DWORD CALLBACK ReadStreamCallback(
296 __in DWORD /*Cookie*/,
297 __out LPBYTE pbBuff,
298 __in LONG cb,
299 __out LONG FAR *pcb
300 )
301{
302 static LPCSTR pszTextBuf = NULL;
303 DWORD er = ERROR_SUCCESS;
304
305 // If it's null set it to the beginning of the EULA buffer
306 if (pszTextBuf == NULL)
307 {
308 pszTextBuf = vpszEulaText;
309 }
310
311 LONG lTextLength = (LONG)lstrlen(pszTextBuf);
312
313 if (cb < 0)
314 {
315 *pcb = 0;
316 er = 1;
317 }
318 else if (lTextLength < cb ) // If the size to be written is less than then length of the buffer, write the rest
319 {
320 *pcb = lTextLength;
321 memcpy(pbBuff, pszTextBuf, *pcb);
322 pszTextBuf = NULL;
323 }
324 else // Only write the amount being asked for and move the pointer along
325 {
326 *pcb = cb;
327 memcpy(pbBuff, pszTextBuf, *pcb);
328 pszTextBuf = pszTextBuf + cb;
329 }
330
331 return er;
332}
333
334
335/********************************************************************
336 LoadEulaText - Reads data for Richedit control
337
338********************************************************************/
339void LoadEulaText(
340 __in HWND hWnd
341 )
342{
343 HRESULT hr = S_OK;
344
345 ExitOnNull(hWnd, hr, ERROR_INVALID_HANDLE, "Invalid Handle passed to LoadEulaText");
346
347 // Docs say this doesn't return any value
348 ::SendMessageW(hWnd, EM_LIMITTEXT, static_cast<WPARAM>(lstrlen(vpszEulaText)), 0);
349
350 EDITSTREAM es;
351 ::ZeroMemory(&es, sizeof(es));
352 es.pfnCallback = (EDITSTREAMCALLBACK)ReadStreamCallback;
353 es.dwCookie = (DWORD)0;
354 ::SendMessageW(hWnd, EM_STREAMIN, SF_RTF, (LPARAM)&es);
355
356 if (0 != es.dwError)
357 {
358 ExitOnLastError(hr, "failed to load the EULA into the control");
359 }
360
361LExit:
362 vhr = hr;
363}
364
365
366/********************************************************************
367 ReadEulaText - Reads Eula text from the MSI
368
369********************************************************************/
370HRESULT ReadEulaText(
371 __in MSIHANDLE /*hInstall*/,
372 __out LPSTR* ppszEulaText
373 )
374{
375 HRESULT hr = S_OK;
376 PMSIHANDLE hDB;
377 PMSIHANDLE hView;
378 PMSIHANDLE hRec;
379 LPWSTR pwzEula = NULL;
380
381 hr = WcaOpenExecuteView(vcsEulaQuery, &hView);
382 ExitOnFailure(hr, "failed to open and execute view for PrintEula query");
383
384 hr = WcaFetchSingleRecord(hView, &hRec);
385 ExitOnFailure(hr, "failed to fetch the row containing the LicenseText");
386
387 hr = WcaGetRecordString(hRec, 1, &pwzEula);
388 ExitOnFailure(hr, "failed to get LicenseText in PrintEula");
389
390 hr = StrAnsiAllocString(ppszEulaText, pwzEula, 0, CP_ACP);
391 ExitOnFailure(hr, "failed to convert LicenseText to ANSI code page");
392
393LExit:
394 return hr;
395}
396
397
398/********************************************************************
399 Print - Function that sends the data from richedit control to the printer
400
401 NOTE: Any errors encountered are saved to the vhr variable
402********************************************************************/
403void Print(
404 __in_opt HWND hRtfWnd
405 )
406{
407 HRESULT hr = S_OK;
408 FORMATRANGE fRange;
409 RECT rcPage;
410 RECT rcPrintablePage;
411 GETTEXTLENGTHEX gTxex;
412 HDC hPrinterDC = vpPrintDlg->hDC;
413 int nHorizRes = ::GetDeviceCaps(hPrinterDC, HORZRES);
414 int nVertRes = ::GetDeviceCaps(hPrinterDC, VERTRES);
415 int nLogPixelsX = ::GetDeviceCaps(hPrinterDC, LOGPIXELSX);
416 //int nLogPixelsY = ::GetDeviceCaps(hPrinterDC, LOGPIXELSY);
417 LONG_PTR lTextLength = 0; // Length of document.
418 LONG_PTR lTextPrinted = 0; // Amount of document printed.
419 DOCINFOW dInfo;
420 LPDEVNAMES pDevnames;
421 LPWSTR sczProductName = NULL;
422 BOOL fStartedDoc = FALSE;
423 BOOL fPrintedSomething = FALSE;
424
425 // Ensure the printer DC is in MM_TEXT mode.
426 if (0 == ::SetMapMode(hPrinterDC, MM_TEXT))
427 {
428 ExitWithLastError(hr, "failed to set map mode");
429 }
430
431 // Rendering to the same DC we are measuring.
432 ::ZeroMemory(&fRange, sizeof(fRange));
433 fRange.hdc = fRange.hdcTarget = hPrinterDC;
434
435 // Set up the page.
436 rcPage.left = rcPage.top = 0;
437 rcPage.right = MulDiv(nHorizRes, ONE_INCH, nLogPixelsX);
438 rcPage.bottom = MulDiv(nVertRes, ONE_INCH, nLogPixelsX);
439
440 // Set up 1" margins all around.
441 rcPrintablePage.left = rcPage.left + ONE_INCH;
442 rcPrintablePage.top = rcPage.top + ONE_INCH;
443 rcPrintablePage.right = rcPage.right - ONE_INCH;
444 rcPrintablePage.bottom = rcPage.bottom - ONE_INCH;
445
446 // Set up the print job (standard printing stuff here).
447 ::ZeroMemory(&dInfo, sizeof(dInfo));
448 dInfo.cbSize = sizeof(DOCINFO);
449 hr = WcaGetProperty(L"ProductName", &sczProductName);
450 if (FAILED(hr))
451 {
452 // If we fail to get the product name, don't fail, just leave it blank;
453 dInfo.lpszDocName = L"";
454 hr = S_OK;
455 }
456 else
457 {
458 dInfo.lpszDocName = sczProductName;
459 }
460
461 pDevnames = (LPDEVNAMES)::GlobalLock(vpPrintDlg->hDevNames);
462 ExitOnNullWithLastError(pDevnames, hr, "failed to get global lock");
463
464 dInfo.lpszOutput = (LPWSTR)pDevnames + pDevnames->wOutputOffset;
465
466 if (0 == ::GlobalUnlock(pDevnames))
467 {
468 ExitWithLastError(hr, "failed to release global lock");
469 }
470
471 // Start the document.
472 if (0 >= ::StartDocW(hPrinterDC, &dInfo))
473 {
474 ExitWithLastError(hr, "failed to start print document");
475 }
476
477 fStartedDoc = TRUE;
478
479 ::ZeroMemory(&gTxex, sizeof(gTxex));
480 gTxex.flags = GTL_NUMCHARS | GTL_PRECISE;
481 lTextLength = ::SendMessageW(hRtfWnd, EM_GETTEXTLENGTHEX, (LONG_PTR)&gTxex, 0);
482
483 while (lTextPrinted < lTextLength)
484 {
485 // Start the page.
486 if (0 >= ::StartPage(hPrinterDC))
487 {
488 ExitWithLastError(hr, "failed to start print page");
489 }
490
491 // Always reset to the full printable page and start where the
492 // last text left off (or zero at the beginning).
493 fRange.rc = rcPrintablePage;
494 fRange.rcPage = rcPage;
495 fRange.chrg.cpMin = (LONG)lTextPrinted;
496 fRange.chrg.cpMax = -1;
497
498 // Print as much text as can fit on a page. The return value is
499 // the index of the first character on the next page. Using TRUE
500 // for the wParam parameter causes the text to be printed.
501 lTextPrinted = ::SendMessageW(hRtfWnd, EM_FORMATRANGE, TRUE, (LPARAM)&fRange);
502 fPrintedSomething = TRUE;
503
504 // If text wasn't printed (i.e. we didn't move past the point we started) then
505 // something must have gone wrong.
506 if (lTextPrinted <= fRange.chrg.cpMin)
507 {
508 hr = E_FAIL;
509 ExitOnFailure(hr, "failed to print some text");
510 }
511
512 // Print last page.
513 if (0 >= ::EndPage(hPrinterDC))
514 {
515 ExitWithLastError(hr, "failed to end print page");
516 }
517 }
518
519LExit:
520 // Tell the control to release cached information, if we actually tried to
521 // print something.
522 if (fPrintedSomething)
523 {
524 ::SendMessageW(hRtfWnd, EM_FORMATRANGE, 0, (LPARAM)NULL);
525 }
526
527 if (fStartedDoc)
528 {
529 ::EndDoc(hPrinterDC);
530 }
531
532 ReleaseStr(sczProductName);
533
534 vhr = hr;
535}
536
537
538/********************************************************************
539 ShowErrorMessage - Display MessageBox showing the message for hr.
540
541********************************************************************/
542void ShowErrorMessage(
543 __in HRESULT hr
544 )
545{
546 WCHAR wzMsg[STRING_CAPACITY];
547
548#pragma prefast(push)
549#pragma prefast(disable:25028)
550 if (0 != ::FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, 0, hr, 0, wzMsg, countof(wzMsg), 0))
551#pragma prefast(pop)
552 {
553 HWND hWnd = ::GetForegroundWindow();
554 ::MessageBoxW(hWnd, wzMsg, L"PrintEULA", MB_OK | MB_ICONWARNING);
555 }
556}
diff --git a/src/ext/UI/ca/uica.def b/src/ext/UI/ca/uica.def
index 62ce8135..41460394 100644
--- a/src/ext/UI/ca/uica.def
+++ b/src/ext/UI/ca/uica.def
@@ -4,5 +4,4 @@
4LIBRARY "uica" 4LIBRARY "uica"
5 5
6EXPORTS 6EXPORTS
7 PrintEula
8 ValidatePath 7 ValidatePath
diff --git a/src/ext/UI/ca/uica.vcxproj b/src/ext/UI/ca/uica.vcxproj
index 0803b252..39c0b404 100644
--- a/src/ext/UI/ca/uica.vcxproj
+++ b/src/ext/UI/ca/uica.vcxproj
@@ -50,7 +50,6 @@
50 <PrecompiledHeader>Create</PrecompiledHeader> 50 <PrecompiledHeader>Create</PrecompiledHeader>
51 </ClCompile> 51 </ClCompile>
52 <ClCompile Include="DriveCheck.cpp" /> 52 <ClCompile Include="DriveCheck.cpp" />
53 <ClCompile Include="PrintEula.cpp" />
54 </ItemGroup> 53 </ItemGroup>
55 54
56 <ItemGroup> 55 <ItemGroup>
diff --git a/src/ext/UI/test/WixToolsetTest.UI/TestData/InstallDir_SpecialDlg/Package.wxs b/src/ext/UI/test/WixToolsetTest.UI/TestData/InstallDir_SpecialDlg/Package.wxs
index 9b10c509..eeb44833 100644
--- a/src/ext/UI/test/WixToolsetTest.UI/TestData/InstallDir_SpecialDlg/Package.wxs
+++ b/src/ext/UI/test/WixToolsetTest.UI/TestData/InstallDir_SpecialDlg/Package.wxs
@@ -43,7 +43,6 @@
43 <?foreach WIXUIARCH in X86;X64;A64 ?> 43 <?foreach WIXUIARCH in X86;X64;A64 ?>
44 <Fragment> 44 <Fragment>
45 <UI Id="InstallDir_SpecialDlg_$(WIXUIARCH)"> 45 <UI Id="InstallDir_SpecialDlg_$(WIXUIARCH)">
46 <Publish Dialog="LicenseAgreementDlg" Control="Print" Event="DoAction" Value="WixUIPrintEula_$(WIXUIARCH)" />
47 <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath_$(WIXUIARCH)" Order="3" Condition="NOT WIXUI_DONTVALIDATEPATH" /> 46 <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath_$(WIXUIARCH)" Order="3" Condition="NOT WIXUI_DONTVALIDATEPATH" />
48 <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath_$(WIXUIARCH)" Order="2" Condition="NOT WIXUI_DONTVALIDATEPATH" /> 47 <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath_$(WIXUIARCH)" Order="2" Condition="NOT WIXUI_DONTVALIDATEPATH" />
49 </UI> 48 </UI>
diff --git a/src/ext/UI/test/WixToolsetTest.UI/UIExtensionFixture.cs b/src/ext/UI/test/WixToolsetTest.UI/UIExtensionFixture.cs
index 45d58e26..eb5e3687 100644
--- a/src/ext/UI/test/WixToolsetTest.UI/UIExtensionFixture.cs
+++ b/src/ext/UI/test/WixToolsetTest.UI/UIExtensionFixture.cs
@@ -37,19 +37,17 @@ namespace WixToolsetTest.UI
37 "CustomAction:WixSetDefaultPerUserFolder\t51\tWixPerUserFolder\t[LocalAppDataFolder]Apps\\[ApplicationFolderName]\t", 37 "CustomAction:WixSetDefaultPerUserFolder\t51\tWixPerUserFolder\t[LocalAppDataFolder]Apps\\[ApplicationFolderName]\t",
38 "CustomAction:WixSetPerMachineFolder\t51\tAPPLICATIONFOLDER\t[WixPerMachineFolder]\t", 38 "CustomAction:WixSetPerMachineFolder\t51\tAPPLICATIONFOLDER\t[WixPerMachineFolder]\t",
39 "CustomAction:WixSetPerUserFolder\t51\tAPPLICATIONFOLDER\t[WixPerUserFolder]\t", 39 "CustomAction:WixSetPerUserFolder\t51\tAPPLICATIONFOLDER\t[WixPerUserFolder]\t",
40 "CustomAction:WixUIPrintEula_X86\t65\tWixUiCa_X86\tPrintEula\t",
41 "CustomAction:WixUIValidatePath_X86\t65\tWixUiCa_X86\tValidatePath\t", 40 "CustomAction:WixUIValidatePath_X86\t65\tWixUiCa_X86\tValidatePath\t",
42 }, results.Where(r => r.StartsWith("CustomAction:")).ToArray()); 41 }, results.Where(r => r.StartsWith("CustomAction:")).ToArray());
43 WixAssert.CompareLineByLine(new[] 42 WixAssert.CompareLineByLine(new[]
44 { 43 {
45 "ControlEvent:AdvancedWelcomeEulaDlg\tPrint\tDoAction\tWixUIPrintEula_X86\t1\t1",
46 "ControlEvent:BrowseDlg\tOK\tDoAction\tWixUIValidatePath_X86\tNOT WIXUI_DONTVALIDATEPATH\t1", 44 "ControlEvent:BrowseDlg\tOK\tDoAction\tWixUIValidatePath_X86\tNOT WIXUI_DONTVALIDATEPATH\t1",
47 "ControlEvent:InstallDirDlg\tNext\tDoAction\tWixUIValidatePath_X86\tNOT WIXUI_DONTVALIDATEPATH\t2", 45 "ControlEvent:InstallDirDlg\tNext\tDoAction\tWixUIValidatePath_X86\tNOT WIXUI_DONTVALIDATEPATH\t2",
48 }, results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")).ToArray()); 46 }, results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")).ToArray());
49 WixAssert.CompareLineByLine(new[] 47 WixAssert.CompareLineByLine(new[]
50 { 48 {
51 "InstallUISequence:AdvancedWelcomeEulaDlg\tNOT Installed\t1296", 49 "InstallUISequence:AdvancedWelcomeEulaDlg\tNOT Installed\t1297",
52 "InstallUISequence:WelcomeDlg\tInstalled AND PATCH\t1295", 50 "InstallUISequence:WelcomeDlg\tInstalled AND PATCH\t1296",
53 }, results.Where(r => r.StartsWith("InstallUISequence:AdvancedWelcome") || r.StartsWith("InstallUISequence:Welcome")).ToArray()); 51 }, results.Where(r => r.StartsWith("InstallUISequence:AdvancedWelcome") || r.StartsWith("InstallUISequence:Welcome")).ToArray());
54 } 52 }
55 53
@@ -78,12 +76,10 @@ namespace WixToolsetTest.UI
78 "CustomAction:WixSetDefaultPerUserFolder\t51\tWixPerUserFolder\t[LocalAppDataFolder]Apps\\[ApplicationFolderName]\t", 76 "CustomAction:WixSetDefaultPerUserFolder\t51\tWixPerUserFolder\t[LocalAppDataFolder]Apps\\[ApplicationFolderName]\t",
79 "CustomAction:WixSetPerMachineFolder\t51\tAPPLICATIONFOLDER\t[WixPerMachineFolder]\t", 77 "CustomAction:WixSetPerMachineFolder\t51\tAPPLICATIONFOLDER\t[WixPerMachineFolder]\t",
80 "CustomAction:WixSetPerUserFolder\t51\tAPPLICATIONFOLDER\t[WixPerUserFolder]\t", 78 "CustomAction:WixSetPerUserFolder\t51\tAPPLICATIONFOLDER\t[WixPerUserFolder]\t",
81 "CustomAction:WixUIPrintEula_X64\t65\tWixUiCa_X64\tPrintEula\t",
82 "CustomAction:WixUIValidatePath_X64\t65\tWixUiCa_X64\tValidatePath\t", 79 "CustomAction:WixUIValidatePath_X64\t65\tWixUiCa_X64\tValidatePath\t",
83 }, results.Where(r => r.StartsWith("CustomAction:")).ToArray()); 80 }, results.Where(r => r.StartsWith("CustomAction:")).ToArray());
84 WixAssert.CompareLineByLine(new[] 81 WixAssert.CompareLineByLine(new[]
85 { 82 {
86 "ControlEvent:AdvancedWelcomeEulaDlg\tPrint\tDoAction\tWixUIPrintEula_X64\t1\t1",
87 "ControlEvent:BrowseDlg\tOK\tDoAction\tWixUIValidatePath_X64\tNOT WIXUI_DONTVALIDATEPATH\t1", 83 "ControlEvent:BrowseDlg\tOK\tDoAction\tWixUIValidatePath_X64\tNOT WIXUI_DONTVALIDATEPATH\t1",
88 "ControlEvent:InstallDirDlg\tNext\tDoAction\tWixUIValidatePath_X64\tNOT WIXUI_DONTVALIDATEPATH\t2", 84 "ControlEvent:InstallDirDlg\tNext\tDoAction\tWixUIValidatePath_X64\tNOT WIXUI_DONTVALIDATEPATH\t2",
89 }, results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")).ToArray()); 85 }, results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")).ToArray());
@@ -114,12 +110,10 @@ namespace WixToolsetTest.UI
114 "CustomAction:WixSetDefaultPerUserFolder\t51\tWixPerUserFolder\t[LocalAppDataFolder]Apps\\[ApplicationFolderName]\t", 110 "CustomAction:WixSetDefaultPerUserFolder\t51\tWixPerUserFolder\t[LocalAppDataFolder]Apps\\[ApplicationFolderName]\t",
115 "CustomAction:WixSetPerMachineFolder\t51\tAPPLICATIONFOLDER\t[WixPerMachineFolder]\t", 111 "CustomAction:WixSetPerMachineFolder\t51\tAPPLICATIONFOLDER\t[WixPerMachineFolder]\t",
116 "CustomAction:WixSetPerUserFolder\t51\tAPPLICATIONFOLDER\t[WixPerUserFolder]\t", 112 "CustomAction:WixSetPerUserFolder\t51\tAPPLICATIONFOLDER\t[WixPerUserFolder]\t",
117 "CustomAction:WixUIPrintEula_A64\t65\tWixUiCa_A64\tPrintEula\t",
118 "CustomAction:WixUIValidatePath_A64\t65\tWixUiCa_A64\tValidatePath\t", 113 "CustomAction:WixUIValidatePath_A64\t65\tWixUiCa_A64\tValidatePath\t",
119 }, results.Where(r => r.StartsWith("CustomAction:")).ToArray()); 114 }, results.Where(r => r.StartsWith("CustomAction:")).ToArray());
120 WixAssert.CompareLineByLine(new[] 115 WixAssert.CompareLineByLine(new[]
121 { 116 {
122 "ControlEvent:AdvancedWelcomeEulaDlg\tPrint\tDoAction\tWixUIPrintEula_A64\t1\t1",
123 "ControlEvent:BrowseDlg\tOK\tDoAction\tWixUIValidatePath_A64\tNOT WIXUI_DONTVALIDATEPATH\t1", 117 "ControlEvent:BrowseDlg\tOK\tDoAction\tWixUIValidatePath_A64\tNOT WIXUI_DONTVALIDATEPATH\t1",
124 "ControlEvent:InstallDirDlg\tNext\tDoAction\tWixUIValidatePath_A64\tNOT WIXUI_DONTVALIDATEPATH\t2", 118 "ControlEvent:InstallDirDlg\tNext\tDoAction\tWixUIValidatePath_A64\tNOT WIXUI_DONTVALIDATEPATH\t2",
125 }, results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")).ToArray()); 119 }, results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")).ToArray());
@@ -144,17 +138,12 @@ namespace WixToolsetTest.UI
144 "Binary:WixUI_Bmp_Up\t[Binary data]", 138 "Binary:WixUI_Bmp_Up\t[Binary data]",
145 "Binary:WixUI_Ico_Exclam\t[Binary data]", 139 "Binary:WixUI_Ico_Exclam\t[Binary data]",
146 "Binary:WixUI_Ico_Info\t[Binary data]", 140 "Binary:WixUI_Ico_Info\t[Binary data]",
147 "Binary:WixUiCa_X64\t[Binary data]",
148 }, results.Where(r => r.StartsWith("Binary:")).ToArray()); 141 }, results.Where(r => r.StartsWith("Binary:")).ToArray());
149 WixAssert.CompareLineByLine(new[] 142 WixAssert.CompareLineByLine(new[]
150 { 143 {
151 "CustomAction:SetWIXUI_EXITDIALOGOPTIONALTEXT\t51\tWIXUI_EXITDIALOGOPTIONALTEXT\tThank you for installing [ProductName].\t", 144 "CustomAction:SetWIXUI_EXITDIALOGOPTIONALTEXT\t51\tWIXUI_EXITDIALOGOPTIONALTEXT\tThank you for installing [ProductName].\t",
152 "CustomAction:WixUIPrintEula_X64\t65\tWixUiCa_X64\tPrintEula\t",
153 }, results.Where(r => r.StartsWith("CustomAction:")).ToArray()); 145 }, results.Where(r => r.StartsWith("CustomAction:")).ToArray());
154 WixAssert.CompareLineByLine(new[] 146 Assert.Empty(results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")));
155 {
156 "ControlEvent:LicenseAgreementDlg\tPrint\tDoAction\tWixUIPrintEula_X64\t1\t1",
157 }, results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")).ToArray());
158 WixAssert.CompareLineByLine(new[] 147 WixAssert.CompareLineByLine(new[]
159 { 148 {
160 "InstallUISequence:WelcomeDlg\tNOT Installed OR PATCH\t1297", 149 "InstallUISequence:WelcomeDlg\tNOT Installed OR PATCH\t1297",
@@ -183,7 +172,6 @@ namespace WixToolsetTest.UI
183 }, results.Where(r => r.StartsWith("Binary:")).ToArray()); 172 }, results.Where(r => r.StartsWith("Binary:")).ToArray());
184 WixAssert.CompareLineByLine(new[] 173 WixAssert.CompareLineByLine(new[]
185 { 174 {
186 "CustomAction:WixUIPrintEula_X86\t65\tWixUiCa_X86\tPrintEula\t",
187 "CustomAction:WixUIValidatePath_X86\t65\tWixUiCa_X86\tValidatePath\t", 175 "CustomAction:WixUIValidatePath_X86\t65\tWixUiCa_X86\tValidatePath\t",
188 }, results.Where(r => r.StartsWith("CustomAction:")).ToArray()); 176 }, results.Where(r => r.StartsWith("CustomAction:")).ToArray());
189 WixAssert.CompareLineByLine(new[] 177 WixAssert.CompareLineByLine(new[]
@@ -194,7 +182,6 @@ namespace WixToolsetTest.UI
194 { 182 {
195 "ControlEvent:BrowseDlg\tOK\tDoAction\tWixUIValidatePath_X86\tNOT WIXUI_DONTVALIDATEPATH\t3", 183 "ControlEvent:BrowseDlg\tOK\tDoAction\tWixUIValidatePath_X86\tNOT WIXUI_DONTVALIDATEPATH\t3",
196 "ControlEvent:InstallDirDlg\tNext\tDoAction\tWixUIValidatePath_X86\tNOT WIXUI_DONTVALIDATEPATH\t2", 184 "ControlEvent:InstallDirDlg\tNext\tDoAction\tWixUIValidatePath_X86\tNOT WIXUI_DONTVALIDATEPATH\t2",
197 "ControlEvent:LicenseAgreementDlg\tPrint\tDoAction\tWixUIPrintEula_X86\t1\t1",
198 }, results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")).OrderBy(s => s).ToArray()); 185 }, results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")).OrderBy(s => s).ToArray());
199 WixAssert.CompareLineByLine(new[] 186 WixAssert.CompareLineByLine(new[]
200 { 187 {
@@ -219,20 +206,13 @@ namespace WixToolsetTest.UI
219 "Binary:WixUI_Bmp_Up\t[Binary data]", 206 "Binary:WixUI_Bmp_Up\t[Binary data]",
220 "Binary:WixUI_Ico_Exclam\t[Binary data]", 207 "Binary:WixUI_Ico_Exclam\t[Binary data]",
221 "Binary:WixUI_Ico_Info\t[Binary data]", 208 "Binary:WixUI_Ico_Info\t[Binary data]",
222 "Binary:WixUiCa_X86\t[Binary data]",
223 }, results.Where(r => r.StartsWith("Binary:")).ToArray()); 209 }, results.Where(r => r.StartsWith("Binary:")).ToArray());
210 Assert.Empty(results.Where(r => r.StartsWith("CustomAction:")));
211 Assert.Empty(results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")));
224 WixAssert.CompareLineByLine(new[] 212 WixAssert.CompareLineByLine(new[]
225 { 213 {
226 "CustomAction:WixUIPrintEula_X86\t65\tWixUiCa_X86\tPrintEula\t", 214 "InstallUISequence:WelcomeDlg\tInstalled AND PATCH\t1296",
227 }, results.Where(r => r.StartsWith("CustomAction:")).ToArray()); 215 "InstallUISequence:WelcomeEulaDlg\tNOT Installed\t1297",
228 WixAssert.CompareLineByLine(new[]
229 {
230 "ControlEvent:WelcomeEulaDlg\tPrint\tDoAction\tWixUIPrintEula_X86\t1\t1",
231 }, results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")).OrderBy(s => s).ToArray());
232 WixAssert.CompareLineByLine(new[]
233 {
234 "InstallUISequence:WelcomeDlg\tInstalled AND PATCH\t1295",
235 "InstallUISequence:WelcomeEulaDlg\tNOT Installed\t1296",
236 }, results.Where(r => r.StartsWith("InstallUISequence:AdvancedWelcome") || r.StartsWith("InstallUISequence:Welcome")).ToArray()); 216 }, results.Where(r => r.StartsWith("InstallUISequence:AdvancedWelcome") || r.StartsWith("InstallUISequence:Welcome")).ToArray());
237 } 217 }
238 218
@@ -297,13 +277,11 @@ namespace WixToolsetTest.UI
297 }, results.Where(r => r.StartsWith("Binary:")).ToArray()); 277 }, results.Where(r => r.StartsWith("Binary:")).ToArray());
298 WixAssert.CompareLineByLine(new[] 278 WixAssert.CompareLineByLine(new[]
299 { 279 {
300 "CustomAction:WixUIPrintEula_X86\t65\tWixUiCa_X86\tPrintEula\t",
301 "CustomAction:WixUIValidatePath_X86\t65\tWixUiCa_X86\tValidatePath\t", 280 "CustomAction:WixUIValidatePath_X86\t65\tWixUiCa_X86\tValidatePath\t",
302 }, results.Where(r => r.StartsWith("CustomAction:")).ToArray()); 281 }, results.Where(r => r.StartsWith("CustomAction:")).ToArray());
303 WixAssert.CompareLineByLine(new[] 282 WixAssert.CompareLineByLine(new[]
304 { 283 {
305 "ControlEvent:BrowseDlg\tOK\tDoAction\tWixUIValidatePath_X86\tNOT WIXUI_DONTVALIDATEPATH\t3", 284 "ControlEvent:BrowseDlg\tOK\tDoAction\tWixUIValidatePath_X86\tNOT WIXUI_DONTVALIDATEPATH\t3",
306 "ControlEvent:LicenseAgreementDlg\tPrint\tDoAction\tWixUIPrintEula_X86\t1\t1",
307 }, results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")).ToArray()); 285 }, results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")).ToArray());
308 WixAssert.CompareLineByLine(new[] 286 WixAssert.CompareLineByLine(new[]
309 { 287 {
@@ -387,7 +365,6 @@ namespace WixToolsetTest.UI
387 }, results.Where(r => r.StartsWith("Binary:")).ToArray()); 365 }, results.Where(r => r.StartsWith("Binary:")).ToArray());
388 WixAssert.CompareLineByLine(new[] 366 WixAssert.CompareLineByLine(new[]
389 { 367 {
390 "CustomAction:WixUIPrintEula_X64\t65\tWixUiCa_X64\tPrintEula\t",
391 "CustomAction:WixUIValidatePath_X64\t65\tWixUiCa_X64\tValidatePath\t", 368 "CustomAction:WixUIValidatePath_X64\t65\tWixUiCa_X64\tValidatePath\t",
392 }, results.Where(r => r.StartsWith("CustomAction:")).ToArray()); 369 }, results.Where(r => r.StartsWith("CustomAction:")).ToArray());
393 WixAssert.CompareLineByLine(new[] 370 WixAssert.CompareLineByLine(new[]
@@ -398,7 +375,6 @@ namespace WixToolsetTest.UI
398 { 375 {
399 "ControlEvent:BrowseDlg\tOK\tDoAction\tWixUIValidatePath_X64\tNOT WIXUI_DONTVALIDATEPATH\t3", 376 "ControlEvent:BrowseDlg\tOK\tDoAction\tWixUIValidatePath_X64\tNOT WIXUI_DONTVALIDATEPATH\t3",
400 "ControlEvent:InstallDirDlg\tNext\tDoAction\tWixUIValidatePath_X64\tNOT WIXUI_DONTVALIDATEPATH\t2", 377 "ControlEvent:InstallDirDlg\tNext\tDoAction\tWixUIValidatePath_X64\tNOT WIXUI_DONTVALIDATEPATH\t2",
401 "ControlEvent:LicenseAgreementDlg\tPrint\tDoAction\tWixUIPrintEula_X64\t1\t1",
402 }, results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")).OrderBy(s => s).ToArray()); 378 }, results.Where(result => result.StartsWith("ControlEvent:") && result.Contains("DoAction")).OrderBy(s => s).ToArray());
403 WixAssert.CompareLineByLine(new[] 379 WixAssert.CompareLineByLine(new[]
404 { 380 {
diff --git a/src/ext/UI/wixlib/AdvancedWelcomeEulaDlg.wxs b/src/ext/UI/wixlib/AdvancedWelcomeEulaDlg.wxs
index 8b950ec1..c8ab1036 100644
--- a/src/ext/UI/wixlib/AdvancedWelcomeEulaDlg.wxs
+++ b/src/ext/UI/wixlib/AdvancedWelcomeEulaDlg.wxs
@@ -11,7 +11,9 @@
11 <Control Id="DescriptionPerMachine" Type="Text" X="20" Y="202" Width="330" Height="31" Transparent="yes" NoPrefix="yes" Hidden="yes" Text="!(loc.AdvancedWelcomeEulaDlgDescriptionPerMachine)" ShowCondition="ALLUSERS" /> 11 <Control Id="DescriptionPerMachine" Type="Text" X="20" Y="202" Width="330" Height="31" Transparent="yes" NoPrefix="yes" Hidden="yes" Text="!(loc.AdvancedWelcomeEulaDlgDescriptionPerMachine)" ShowCondition="ALLUSERS" />
12 <Control Id="DescriptionPerUser" Type="Text" X="20" Y="202" Width="330" Height="31" Transparent="yes" NoPrefix="yes" Hidden="yes" Text="!(loc.AdvancedWelcomeEulaDlgDescriptionPerUser)" ShowCondition="NOT ALLUSERS" /> 12 <Control Id="DescriptionPerUser" Type="Text" X="20" Y="202" Width="330" Height="31" Transparent="yes" NoPrefix="yes" Hidden="yes" Text="!(loc.AdvancedWelcomeEulaDlgDescriptionPerUser)" ShowCondition="NOT ALLUSERS" />
13 <Control Id="LicenseAcceptedCheckBox" Type="CheckBox" X="20" Y="180" Width="226" Height="18" CheckBoxValue="1" Property="LicenseAccepted" Text="!(loc.WelcomeEulaDlgLicenseAcceptedCheckBox)" /> 13 <Control Id="LicenseAcceptedCheckBox" Type="CheckBox" X="20" Y="180" Width="226" Height="18" CheckBoxValue="1" Property="LicenseAccepted" Text="!(loc.WelcomeEulaDlgLicenseAcceptedCheckBox)" />
14 <Control Id="Print" Type="PushButton" X="88" Y="243" Width="56" Height="17" Text="!(loc.WixUIPrint)" /> 14 <Control Id="Print" Type="PushButton" X="88" Y="243" Width="56" Height="17" Text="!(loc.WixUIPrint)">
15 <Publish Event="MsiPrint" Value="1" />
16 </Control>
15 <Control Id="Advanced" Type="PushButton" X="156" Y="243" Width="56" Height="17" Text="!(loc.AdvancedWelcomeEulaDlgAdvanced)" DisableCondition="LicenseAccepted &lt;&gt; &quot;1&quot;" EnableCondition="LicenseAccepted = &quot;1&quot;" /> 17 <Control Id="Advanced" Type="PushButton" X="156" Y="243" Width="56" Height="17" Text="!(loc.AdvancedWelcomeEulaDlgAdvanced)" DisableCondition="LicenseAccepted &lt;&gt; &quot;1&quot;" EnableCondition="LicenseAccepted = &quot;1&quot;" />
16 <Control Id="Install" Type="PushButton" ElevationShield="yes" X="212" Y="243" Width="80" Height="17" Default="yes" Text="!(loc.AdvancedWelcomeEulaDlgInstall)" Hidden="yes" DisableCondition="LicenseAccepted &lt;&gt; &quot;1&quot;" EnableCondition="LicenseAccepted = &quot;1&quot;" ShowCondition="ALLUSERS"> 18 <Control Id="Install" Type="PushButton" ElevationShield="yes" X="212" Y="243" Width="80" Height="17" Default="yes" Text="!(loc.AdvancedWelcomeEulaDlgInstall)" Hidden="yes" DisableCondition="LicenseAccepted &lt;&gt; &quot;1&quot;" EnableCondition="LicenseAccepted = &quot;1&quot;" ShowCondition="ALLUSERS">
17 <Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg" Condition="!(wix.WixUICostingPopupOptOut) OR CostingComplete = 1" /> 19 <Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg" Condition="!(wix.WixUICostingPopupOptOut) OR CostingComplete = 1" />
diff --git a/src/ext/UI/wixlib/Common_Platform.wxi b/src/ext/UI/wixlib/Common_Platform.wxi
index 329abb2e..51fff6a1 100644
--- a/src/ext/UI/wixlib/Common_Platform.wxi
+++ b/src/ext/UI/wixlib/Common_Platform.wxi
@@ -5,10 +5,6 @@
5 <?include ..\..\caDecor.wxi ?> 5 <?include ..\..\caDecor.wxi ?>
6 6
7 <Fragment> 7 <Fragment>
8 <CustomAction Id="WixUIPrintEula$(Suffix)" BinaryRef="WixUiCa$(Suffix)" DllEntry="PrintEula" Return="ignore" Execute="immediate" />
9 </Fragment>
10
11 <Fragment>
12 <CustomAction Id="WixUIValidatePath$(Suffix)" BinaryRef="WixUiCa$(Suffix)" DllEntry="ValidatePath" Return="ignore" Execute="immediate" /> 8 <CustomAction Id="WixUIValidatePath$(Suffix)" BinaryRef="WixUiCa$(Suffix)" DllEntry="ValidatePath" Return="ignore" Execute="immediate" />
13 </Fragment> 9 </Fragment>
14 10
diff --git a/src/ext/UI/wixlib/LicenseAgreementDlg.wxs b/src/ext/UI/wixlib/LicenseAgreementDlg.wxs
index a072cf6b..96585b29 100644
--- a/src/ext/UI/wixlib/LicenseAgreementDlg.wxs
+++ b/src/ext/UI/wixlib/LicenseAgreementDlg.wxs
@@ -11,7 +11,9 @@
11 <Control Id="Description" Type="Text" X="25" Y="23" Width="340" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.LicenseAgreementDlgDescription)" /> 11 <Control Id="Description" Type="Text" X="25" Y="23" Width="340" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.LicenseAgreementDlgDescription)" />
12 <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.LicenseAgreementDlgTitle)" /> 12 <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.LicenseAgreementDlgTitle)" />
13 <Control Id="LicenseAcceptedCheckBox" Type="CheckBox" X="20" Y="207" Width="330" Height="18" CheckBoxValue="1" Property="LicenseAccepted" Text="!(loc.LicenseAgreementDlgLicenseAcceptedCheckBox)" /> 13 <Control Id="LicenseAcceptedCheckBox" Type="CheckBox" X="20" Y="207" Width="330" Height="18" CheckBoxValue="1" Property="LicenseAccepted" Text="!(loc.LicenseAgreementDlgLicenseAcceptedCheckBox)" />
14 <Control Id="Print" Type="PushButton" X="112" Y="243" Width="56" Height="17" Text="!(loc.WixUIPrint)" /> 14 <Control Id="Print" Type="PushButton" X="112" Y="243" Width="56" Height="17" Text="!(loc.WixUIPrint)">
15 <Publish Event="MsiPrint" Value="1" />
16 </Control>
15 <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" /> 17 <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" />
16 <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)" DisableCondition="LicenseAccepted &lt;&gt; &quot;1&quot;" EnableCondition="LicenseAccepted = &quot;1&quot;"> 18 <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)" DisableCondition="LicenseAccepted &lt;&gt; &quot;1&quot;" EnableCondition="LicenseAccepted = &quot;1&quot;">
17 <Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg" Condition="!(wix.WixUICostingPopupOptOut) OR CostingComplete = 1" /> 19 <Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg" Condition="!(wix.WixUICostingPopupOptOut) OR CostingComplete = 1" />
diff --git a/src/ext/UI/wixlib/WelcomeEulaDlg.wxs b/src/ext/UI/wixlib/WelcomeEulaDlg.wxs
index ee01d29a..a95a9274 100644
--- a/src/ext/UI/wixlib/WelcomeEulaDlg.wxs
+++ b/src/ext/UI/wixlib/WelcomeEulaDlg.wxs
@@ -9,7 +9,9 @@
9 <Control Id="Title" Type="Text" X="130" Y="6" Width="225" Height="30" Transparent="yes" NoPrefix="yes" Text="!(loc.WelcomeEulaDlgTitle)" /> 9 <Control Id="Title" Type="Text" X="130" Y="6" Width="225" Height="30" Transparent="yes" NoPrefix="yes" Text="!(loc.WelcomeEulaDlgTitle)" />
10 <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" /> 10 <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
11 <Control Id="LicenseAcceptedCheckBox" Type="CheckBox" X="130" Y="207" Width="226" Height="18" CheckBoxValue="1" Property="LicenseAccepted" Text="!(loc.WelcomeEulaDlgLicenseAcceptedCheckBox)" /> 11 <Control Id="LicenseAcceptedCheckBox" Type="CheckBox" X="130" Y="207" Width="226" Height="18" CheckBoxValue="1" Property="LicenseAccepted" Text="!(loc.WelcomeEulaDlgLicenseAcceptedCheckBox)" />
12 <Control Id="Print" Type="PushButton" X="88" Y="243" Width="56" Height="17" Text="!(loc.WixUIPrint)" /> 12 <Control Id="Print" Type="PushButton" X="88" Y="243" Width="56" Height="17" Text="!(loc.WixUIPrint)">
13 <Publish Event="MsiPrint" Value="1" />
14 </Control>
13 <Control Id="Back" Type="PushButton" X="156" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUIBack)" /> 15 <Control Id="Back" Type="PushButton" X="156" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUIBack)" />
14 <Control Id="Install" Type="PushButton" ElevationShield="yes" X="212" Y="243" Width="80" Height="17" Default="yes" Text="!(loc.WelcomeEulaDlgInstall)" Hidden="yes" DisableCondition="LicenseAccepted &lt;&gt; &quot;1&quot;" EnableCondition="LicenseAccepted = &quot;1&quot;" ShowCondition="ALLUSERS"> 16 <Control Id="Install" Type="PushButton" ElevationShield="yes" X="212" Y="243" Width="80" Height="17" Default="yes" Text="!(loc.WelcomeEulaDlgInstall)" Hidden="yes" DisableCondition="LicenseAccepted &lt;&gt; &quot;1&quot;" EnableCondition="LicenseAccepted = &quot;1&quot;" ShowCondition="ALLUSERS">
15 <Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg" Condition="!(wix.WixUICostingPopupOptOut) OR CostingComplete = 1" /> 17 <Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg" Condition="!(wix.WixUICostingPopupOptOut) OR CostingComplete = 1" />
diff --git a/src/ext/UI/wixlib/WixUI_Advanced.wxs b/src/ext/UI/wixlib/WixUI_Advanced.wxs
index 4f8bfa0c..2050dc24 100644
--- a/src/ext/UI/wixlib/WixUI_Advanced.wxs
+++ b/src/ext/UI/wixlib/WixUI_Advanced.wxs
@@ -23,7 +23,6 @@ Todo:
23 <?foreach WIXUIARCH in X86;X64;A64 ?> 23 <?foreach WIXUIARCH in X86;X64;A64 ?>
24 <Fragment> 24 <Fragment>
25 <UI Id="WixUI_Advanced_$(WIXUIARCH)"> 25 <UI Id="WixUI_Advanced_$(WIXUIARCH)">
26 <Publish Dialog="AdvancedWelcomeEulaDlg" Control="Print" Event="DoAction" Value="WixUIPrintEula_$(WIXUIARCH)" />
27 <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath_$(WIXUIARCH)" Order="1" Condition="NOT WIXUI_DONTVALIDATEPATH" /> 26 <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath_$(WIXUIARCH)" Order="1" Condition="NOT WIXUI_DONTVALIDATEPATH" />
28 <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath_$(WIXUIARCH)" Order="2" Condition="NOT WIXUI_DONTVALIDATEPATH" /> 27 <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath_$(WIXUIARCH)" Order="2" Condition="NOT WIXUI_DONTVALIDATEPATH" />
29 </UI> 28 </UI>
diff --git a/src/ext/UI/wixlib/WixUI_FeatureTree.wxs b/src/ext/UI/wixlib/WixUI_FeatureTree.wxs
index 6b9b1cf3..5ec27445 100644
--- a/src/ext/UI/wixlib/WixUI_FeatureTree.wxs
+++ b/src/ext/UI/wixlib/WixUI_FeatureTree.wxs
@@ -22,10 +22,7 @@ Patch dialog sequence:
22<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> 22<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
23 <?foreach WIXUIARCH in X86;X64;A64 ?> 23 <?foreach WIXUIARCH in X86;X64;A64 ?>
24 <Fragment> 24 <Fragment>
25 <UI Id="WixUI_FeatureTree_$(WIXUIARCH)"> 25 <UI Id="WixUI_FeatureTree_$(WIXUIARCH)" />
26 <Publish Dialog="LicenseAgreementDlg" Control="Print" Event="DoAction" Value="WixUIPrintEula_$(WIXUIARCH)" />
27 </UI>
28
29 <UIRef Id="WixUI_FeatureTree" /> 26 <UIRef Id="WixUI_FeatureTree" />
30 </Fragment> 27 </Fragment>
31 <?endforeach?> 28 <?endforeach?>
diff --git a/src/ext/UI/wixlib/WixUI_InstallDir.wxs b/src/ext/UI/wixlib/WixUI_InstallDir.wxs
index e3c171df..bbe806bd 100644
--- a/src/ext/UI/wixlib/WixUI_InstallDir.wxs
+++ b/src/ext/UI/wixlib/WixUI_InstallDir.wxs
@@ -24,7 +24,6 @@ Patch dialog sequence:
24 <?foreach WIXUIARCH in X86;X64;A64 ?> 24 <?foreach WIXUIARCH in X86;X64;A64 ?>
25 <Fragment> 25 <Fragment>
26 <UI Id="WixUI_InstallDir_$(WIXUIARCH)"> 26 <UI Id="WixUI_InstallDir_$(WIXUIARCH)">
27 <Publish Dialog="LicenseAgreementDlg" Control="Print" Event="DoAction" Value="WixUIPrintEula_$(WIXUIARCH)" />
28 <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath_$(WIXUIARCH)" Order="3" Condition="NOT WIXUI_DONTVALIDATEPATH" /> 27 <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath_$(WIXUIARCH)" Order="3" Condition="NOT WIXUI_DONTVALIDATEPATH" />
29 <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath_$(WIXUIARCH)" Order="2" Condition="NOT WIXUI_DONTVALIDATEPATH" /> 28 <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath_$(WIXUIARCH)" Order="2" Condition="NOT WIXUI_DONTVALIDATEPATH" />
30 </UI> 29 </UI>
diff --git a/src/ext/UI/wixlib/WixUI_Minimal.wxs b/src/ext/UI/wixlib/WixUI_Minimal.wxs
index 80a011e6..df71e995 100644
--- a/src/ext/UI/wixlib/WixUI_Minimal.wxs
+++ b/src/ext/UI/wixlib/WixUI_Minimal.wxs
@@ -17,10 +17,7 @@ Patch dialog sequence:
17<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> 17<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
18 <?foreach WIXUIARCH in X86;X64;A64 ?> 18 <?foreach WIXUIARCH in X86;X64;A64 ?>
19 <Fragment> 19 <Fragment>
20 <UI Id="WixUI_Minimal_$(WIXUIARCH)"> 20 <UI Id="WixUI_Minimal_$(WIXUIARCH)" />
21 <Publish Dialog="WelcomeEulaDlg" Control="Print" Event="DoAction" Value="WixUIPrintEula_$(WIXUIARCH)" />
22 </UI>
23
24 <UIRef Id="WixUI_Minimal" /> 21 <UIRef Id="WixUI_Minimal" />
25 </Fragment> 22 </Fragment>
26 <?endforeach?> 23 <?endforeach?>
diff --git a/src/ext/UI/wixlib/WixUI_Mondo.wxs b/src/ext/UI/wixlib/WixUI_Mondo.wxs
index aac13112..4dd1148d 100644
--- a/src/ext/UI/wixlib/WixUI_Mondo.wxs
+++ b/src/ext/UI/wixlib/WixUI_Mondo.wxs
@@ -25,7 +25,6 @@ Patch dialog sequence:
25 <?foreach WIXUIARCH in X86;X64;A64 ?> 25 <?foreach WIXUIARCH in X86;X64;A64 ?>
26 <Fragment> 26 <Fragment>
27 <UI Id="WixUI_Mondo_$(WIXUIARCH)"> 27 <UI Id="WixUI_Mondo_$(WIXUIARCH)">
28 <Publish Dialog="LicenseAgreementDlg" Control="Print" Event="DoAction" Value="WixUIPrintEula_$(WIXUIARCH)" />
29 <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath_$(WIXUIARCH)" Order="3" Condition="NOT WIXUI_DONTVALIDATEPATH" /> 28 <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath_$(WIXUIARCH)" Order="3" Condition="NOT WIXUI_DONTVALIDATEPATH" />
30 </UI> 29 </UI>
31 30
diff --git a/src/wix/WixToolset.Converters/WixConverter.cs b/src/wix/WixToolset.Converters/WixConverter.cs
index be51d6c7..a4de1d21 100644
--- a/src/wix/WixToolset.Converters/WixConverter.cs
+++ b/src/wix/WixToolset.Converters/WixConverter.cs
@@ -1705,11 +1705,20 @@ namespace WixToolset.Converters
1705 var eventName = element.Attribute("Event")?.Value; 1705 var eventName = element.Attribute("Event")?.Value;
1706 var eventValue = element.Attribute("Value")?.Value; 1706 var eventValue = element.Attribute("Value")?.Value;
1707 1707
1708 if (eventName?.Equals("DoAction", StringComparison.OrdinalIgnoreCase) == true 1708 if (eventName?.Equals("DoAction", StringComparison.OrdinalIgnoreCase) == true)
1709 && eventValue?.StartsWith("WixUI", StringComparison.OrdinalIgnoreCase) == true
1710 && this.OnInformation(ConverterTestType.CustomActionIdsIncludePlatformSuffix, element, "Custom action ids have changed in WiX v4 extensions to support platform-specific custom actions. For more information, see https://wixtoolset.org/docs/fourthree/#converting-custom-wixui-dialog-sets."))
1711 { 1709 {
1712 element.Attribute("Value").Value = eventValue + "_$(sys.BUILDARCHSHORT)"; 1710 if (eventValue?.StartsWith("WixUIPrintEula", StringComparison.OrdinalIgnoreCase) == true)
1711 {
1712 if (this.OnInformation(ConverterTestType.WixUIPrintEulaCustomAction, element, "The WixUIPrintEula custom action has been replaced with the MSI native MsiPrint control event in WiX v5 and no longer needs to be authored in a custom dialog set."))
1713 {
1714 element.Remove();
1715 }
1716 }
1717 else if (eventValue?.StartsWith("WixUI", StringComparison.OrdinalIgnoreCase) == true
1718 && this.OnInformation(ConverterTestType.CustomActionIdsIncludePlatformSuffix, element, "Custom action ids have changed in WiX v4 extensions to support platform-specific custom actions. For more information, see https://wixtoolset.org/docs/fourthree/faqs/#converting-custom-wixui-dialog-sets."))
1719 {
1720 element.Attribute("Value").Value = eventValue + "_$(sys.BUILDARCHSHORT)";
1721 }
1713 } 1722 }
1714 } 1723 }
1715 1724
@@ -3546,6 +3555,11 @@ namespace WixToolset.Converters
3546 /// The RelatedBundle element's Action attribute value must now be all lowercase. The Action='{0}' will be converted to '{1}' 3555 /// The RelatedBundle element's Action attribute value must now be all lowercase. The Action='{0}' will be converted to '{1}'
3547 /// </summary> 3556 /// </summary>
3548 RelatedBundleActionLowercase, 3557 RelatedBundleActionLowercase,
3558
3559 /// <summary>
3560 /// The WixUIPrintEula custom action has been replaced with the MSI native MsiPrint control event in WiX v5 and no longer needs to be authored in a custom dialog set.
3561 /// </summary>
3562 WixUIPrintEulaCustomAction,
3549 } 3563 }
3550 } 3564 }
3551} 3565}
diff --git a/src/wix/test/WixToolsetTest.Converters/UIExtensionFixture.cs b/src/wix/test/WixToolsetTest.Converters/UIExtensionFixture.cs
index 168751f4..a562fb59 100644
--- a/src/wix/test/WixToolsetTest.Converters/UIExtensionFixture.cs
+++ b/src/wix/test/WixToolsetTest.Converters/UIExtensionFixture.cs
@@ -58,17 +58,13 @@ namespace WixToolsetTest.Converters
58 } 58 }
59 59
60 [Fact] 60 [Fact]
61 public void FixPrintCustomAction() 61 public void RemovePrintCustomAction()
62 { 62 {
63 var parse = String.Join(Environment.NewLine, 63 var parse = String.Join(Environment.NewLine,
64 "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>", 64 "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>",
65 " <Fragment>", 65 " <Fragment>",
66 " <UI>", 66 " <UI Id=\"WixUI_Advanced_$(WIXUIARCH)\">",
67 " <Dialog Id='CustomResumeDlg' Width='370' Height='270' Title='!(loc.ResumeDlg_Title)'>", 67 " <Publish Dialog=\"AdvancedWelcomeEulaDlg\" Control=\"Print\" Event=\"DoAction\" Value=\"WixUIPrintEula_$(WIXUIARCH)\" />",
68 " <Control Id='Print' Type='PushButton' X='112' Y='243' Width='56' Height='17' Text='!(loc.WixUIPrint)'>",
69 " <Publish Event='DoAction' Value='WixUIPrintEula'>1</Publish>",
70 " </Control>",
71 " </Dialog>",
72 " </UI>", 68 " </UI>",
73 " </Fragment>", 69 " </Fragment>",
74 "</Wix>"); 70 "</Wix>");
@@ -77,12 +73,8 @@ namespace WixToolsetTest.Converters
77 { 73 {
78 "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">", 74 "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
79 " <Fragment>", 75 " <Fragment>",
80 " <UI>", 76 " <UI Id=\"WixUI_Advanced_$(WIXUIARCH)\">",
81 " <Dialog Id=\"CustomResumeDlg\" Width=\"370\" Height=\"270\" Title=\"!(loc.ResumeDlg_Title)\">", 77 " ",
82 " <Control Id=\"Print\" Type=\"PushButton\" X=\"112\" Y=\"243\" Width=\"56\" Height=\"17\" Text=\"!(loc.WixUIPrint)\">",
83 " <Publish Event=\"DoAction\" Value=\"WixUIPrintEula_$(sys.BUILDARCHSHORT)\" />",
84 " </Control>",
85 " </Dialog>",
86 " </UI>", 78 " </UI>",
87 " </Fragment>", 79 " </Fragment>",
88 "</Wix>" 80 "</Wix>"
@@ -98,7 +90,7 @@ namespace WixToolsetTest.Converters
98 var actual = UnformattedDocumentLines(document); 90 var actual = UnformattedDocumentLines(document);
99 91
100 WixAssert.CompareLineByLine(expected, actual); 92 WixAssert.CompareLineByLine(expected, actual);
101 Assert.Equal(4, errors); 93 Assert.Equal(2, errors);
102 } 94 }
103 95
104 [Fact] 96 [Fact]